Skip to content

Conversation

@kyrers
Copy link

@kyrers kyrers commented Oct 23, 2025

Resolves #88.


PR-Codex overview

This PR focuses on refactoring the codebase by removing styled-components, replacing them with Tailwind CSS classes, and updating various components to improve performance and maintainability.

Detailed summary

  • Removed multiple styled-components and replaced with Tailwind CSS classes.
  • Standardized button props from disabled to isDisabled.
  • Introduced new utility functions for class merging.
  • Updated various components to improve accessibility and responsiveness.
  • Added new constants for breakpoint calculations.

The following files were skipped due to too many changes: web/src/components/ItemCard/ItemField/index.tsx, web/src/layout/Header/MobileHeader.tsx, web/src/pages/AllLists/RegistryDetails/ItemsDownloadLabel.tsx, web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/FormContact.tsx, web/src/pages/Home/Stats/index.tsx, web/src/layout/Header/navbar/Menu/Settings/Notifications/index.tsx, web/src/components/ActionButton/index.tsx, web/src/pages/AllLists/index.tsx, web/src/pages/SubmitItem/ItemField/index.tsx, web/package.json, web/src/pages/SubmitItem/ItemField/FieldInput/ImageInput.tsx, web/src/pages/AllLists/StyledBreadcrumb.tsx, web/src/pages/SubmitItem/ItemField/FieldInput/FileInput.tsx, web/src/layout/index.tsx, web/src/components/HistoryDisplay/Party/index.tsx, web/src/pages/SubmitList/ListParameters/ListPreview/ListPageDisplay.tsx, web/src/components/RegistryCard/index.tsx, web/src/pages/Home/Highlights/index.tsx, web/src/components/ItemCard/ItemField/LongTextField.tsx, web/src/components/InformationCards/ItemInformationCard/FieldsDisplay.tsx, web/src/pages/SubmitList/ListParameters/ListPreview/index.tsx, web/src/components/HistoryDisplay/Party/JustificationDetails.tsx, web/src/components/LightButton.tsx, web/src/components/HistoryDisplay/Party/JustificationModal.tsx, web/src/layout/Header/index.tsx, web/src/pages/SubmitItem/Preview/index.tsx, web/src/layout/Header/navbar/Menu/index.tsx, web/src/pages/SubmitList/ListParameters/LogoUpload.tsx, web/src/pages/SubmitList/ListParameters/Title.tsx, web/src/layout/Header/navbar/Product.tsx, web/src/layout/Footer/index.tsx, web/src/pages/SubmitList/ListParameters/Description.tsx, web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/EmailVerificationInfo.tsx, web/src/layout/Header/navbar/index.tsx, web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx, web/src/pages/SubmitItem/index.tsx, web/src/layout/Header/navbar/Menu/Help.tsx, web/src/components/StatsAndFilters/Filters.tsx, web/src/pages/SubmitList/ListParameters/Policy.tsx, web/src/components/RegistriesDisplay/RegistriesGrid.tsx, web/src/components/StyledSkeleton.tsx, web/src/components/ActionButton/Modal/EvidenceUpload.tsx, web/src/layout/Header/navbar/Explore.tsx, web/src/layout/Header/navbar/DappList.tsx, web/src/layout/Header/DesktopHeader.tsx, web/src/components/StatDisplay.tsx, web/src/components/InformationCards/RegistryInformationCard/index.tsx, web/src/layout/Header/navbar/Menu/Settings/General.tsx, web/src/components/InformationCards/StatusDisplay.tsx, web/src/layout/Header/navbar/Menu/Settings/index.tsx, web/src/pages/SubmitItem/Header/index.tsx, web/src/components/InformationCards/RegistryInformationCard/Policies.tsx, web/src/components/LabeledInput.tsx, web/src/components/ItemCard/index.tsx, web/src/components/RegistryCard/StatusBanner.tsx, web/src/global.css, web/src/components/ConnectWallet/AccountDisplay.tsx, web/src/components/Search.tsx, web/src/components/InformationCards/RegistryInformationCard/TopInfo.tsx, web/src/components/InformationCards/ItemInformationCard/index.tsx, web/src/components/RegistryCard/RegistryInfo.tsx, web/src/components/HistoryDisplay/index.tsx, yarn.lock

✨ Ask PR-Codex anything about this PR by commenting with /codex {your question}

Summary by CodeRabbit

  • Chores

    • Added Tailwind tooling and utilities, upgraded UI library, and removed legacy styling/modal packages.
  • New Features

    • New theme provider with persisted light/dark preference and a global stylesheet for typography, scrollbars, and toasts.
  • Refactor

    • Large migration from CSS-in-JS to utility/class-based styling across the app.
  • Other

    • Added class-name merge helper and large-breakpoint constant; standardized Button disable prop and Modal className; minor prop/interface surface updates.

@kyrers kyrers self-assigned this Oct 23, 2025
@netlify
Copy link

netlify bot commented Oct 23, 2025

Deploy Preview for curate-v2 failed. Why did it fail? →

Name Link
🔨 Latest commit 6cf84d1
🔍 Latest deploy log https://app.netlify.com/projects/curate-v2/deploys/691e21903f7042000831d01f

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 23, 2025

Walkthrough

Replaces styled-components with Tailwind/className across the web frontend, adds Tailwind tooling and global.css, upgrades @kleros/ui-components-library to v3, introduces cn and LG_BREAKPOINT, swaps StyledComponentsProvider for a DOM-class ThemeProvider, and updates Button prop usage disabledisDisabled.

Changes

Cohort / File(s) Change Summary
Deps & Build
\web/package.json`, `web/vite.config.js``
Add Tailwind tooling (@tailwindcss/vite, tailwindcss), add clsx & tailwind-merge, upgrade @kleros/ui-components-library to v3; register Tailwind plugin in Vite.
App & Providers
New: \web/src/context/ThemeProvider.tsx`<br> **Deleted:**`web/src/context/StyledComponentsProvider.tsx`<br>`web/src/app.tsx`, `web/src/index.tsx``
Replace StyledComponentsProvider with ThemeProvider that persists theme and toggles dark class; import global.css; remove react-modal setAppElement.
Global CSS & types
New: \web/src/global.css`, `web/global.d.ts``
Add centralized Tailwind/global styles and tokens; convert global.d.ts from styled-components augmentation to a module; keep asset declarations.
Styles removed
\web/src/styles/... (themes.ts, global-style.ts, customScrollbar.ts, commonStyles.ts, landscapeStyle.ts)``
Remove styled-components theme files, global styled rules and helpers; visuals migrated to global.css and utility classes.
Breakpoints & utils
\web/src/styles/breakpoints.ts`, `web/src/utils/index.ts``
Add LG_BREAKPOINT = 900; add cn(...inputs) helper (clsx + tailwind-merge).
Hook rename / theme API
\web/src/hooks/useToggleThemeContext.tsx`, consumers (e.g. `web/src/components/HeroImage.tsx``)
Rename export useToggleThemeuseTheme; consumer usage changed to destructure [theme, toggleTheme] and treat theme as a string.
Button API updates
many files (e.g. \web/src/components/EnsureAuth.tsx`, `web/src/components/ConnectWallet/**``, action buttons)
Replace Button prop disabledisDisabled to match UI lib v3.
Modal / Overlay / Portal
\web/src/components/Modal.tsx`, `web/src/components/Overlay.tsx`, `web/src/components/OverlayPortal.tsx`, `web/src/components/ActionButton/Modal/**``
Remove styled-components wrappers, switch to className-based divs; Modal now accepts optional className.
Layouts & pages
\web/src/layout/`, `web/src/pages/``
Migrate header, navbar, menus, settings, footer and page wrappers from styled-components to utility class-based markup; remove overlayscrollbars import where replaced.
Bulk component migrations
\web/src/components/**`` (many files)
Convert numerous components from styled-components to className/Tailwind; add/extend some interfaces with optional className; remove styled-only exports (ExternalLink, InternalLink).
Registry, Status & Cards
\web/src/components/RegistryCard/`, `web/src/components/StatDisplay.tsx`, `web/src/components/RegistryInfo/``
Move status color logic to class mappings, remove getStatusColor, update interfaces (IListCard, IColors), rework rendering to utility classes.
Forms & inputs / Submit flows
\web/src/components/LabeledInput.tsx`, `web/src/pages/SubmitItem/**``, many input components
Migrate inputs to UI lib v3 components (TextField/TextArea) with value-based onChange handlers; remove styled wrappers; add layout constants and responsive class strings.
Breakpoints migration
multiple hooks/pages (e.g. \web/src/hooks/useIsDesktop.tsx`, `web/src/pages/AllLists/**``)
Replace BREAKPOINT_LANDSCAPE usages with LG_BREAKPOINT.
Interface / signature deltas
assorted files (e.g. \web/src/components/Modal.tsx``, Settings, InfoCard, RegistryCard, NumberField, AliasDisplay)
Add Modal.className?; remove Settings.initialTab; expand/modify several interfaces and add optional className or new props (see diff for specifics).

Sequence Diagram(s)

sequenceDiagram
    participant App as App
    participant ThemeProv as ThemeProvider
    participant Doc as document.documentElement
    participant ToggleCtx as ToggleThemeProvider
    participant UI as UI Component

    App->>ThemeProv: mount ThemeProvider(children)
    ThemeProv->>ThemeProv: load theme from localStorage (default "dark")
    ThemeProv->>Doc: add/remove "dark" CSS class
    ThemeProv->>ToggleCtx: provide [theme, toggleTheme]
    UI->>ToggleCtx: consume [theme, toggleTheme]
    UI->>UI: render using cn(...) (clsx + twMerge)
    UI->>ThemeProv: user triggers toggleTheme()
    ThemeProv->>ThemeProv: persist theme and update DOM class
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

  • Files/areas needing extra attention:
    • web/src/global.css — tokens, Toastify and skeleton overrides, scrollbar rules.
    • web/global.d.ts and removals of web/src/styles/themes.ts — ensure no remaining styled-components DefaultTheme references or type regressions.
    • Hook rename (useToggleThemeuseTheme) — verify all consumers and typings updated.
    • Button API migration — search for lingering disabled usages vs isDisabled.
    • Interface/signature changes: Modal.className?, Settings.initialTab removal, IListCard additions, NumberField prop changes, RegistriesGrid prop expansion.
    • Large-scale styled→class migration spots where behavior previously relied on theme tokens (colors, overlays, scrollbars).

Possibly related issues

Possibly related PRs

Suggested labels

Package: Web, Type: Enhancement :sparkles:

Suggested reviewers

  • kemuru
  • Harman-singh-waraich
  • alcercu

Poem

🐇 I hopped through styles and traded threads for classes,
Tailwind stitched the pages, lighter on the masses.
Theme flips in localStorage, dark on the root,
cn joins the chorus, keeping classnames cute.
🥕 Hop, review, merge — then share a crunchy carrot.

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'chore: migrate from styled components to tailwind' clearly and concisely summarizes the main change: replacing styled-components with Tailwind CSS across the codebase.
Linked Issues check ✅ Passed The PR comprehensively addresses all coding requirements from issue #88: migrating to @kleros/ui-components-library v3, replacing styled-components with Tailwind, updating component APIs (disabled→isDisabled), integrating Tailwind configuration, and implementing a ThemeProvider.
Out of Scope Changes check ✅ Passed All changes are directly in-scope with issue #88: dependency updates, styled-components removal, Tailwind integration, component refactoring, and theme provider replacement are all explicitly required for the v3 migration.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch chore/migrate-from-styled-components-to-tailwind

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
web/src/global.css (1)

60-62: Consider reducing !important usage.

The !important declarations on lines 61 and 147 override library defaults for ReactModal and Toastify. While sometimes necessary for third-party library overrides, consider if these can be achieved through higher CSS specificity instead.

If the library CSS is loaded before your global styles, you may be able to increase specificity without !important:

/* Instead of: */
.ReactModal__Overlay {
  background-color: #1b003fcc !important;
}

/* Try: */
.ReactModal__Overlay.ReactModal__Overlay {
  background-color: #1b003fcc;
}

Also applies to: 145-148

web/src/context/ThemeProvider.tsx (1)

8-8: Improve type safety for theme values.

The theme is currently typed as string, which allows any string value. This should be constrained to the valid theme values for better type safety and developer experience.

Apply this diff to add proper typing:

+type Theme = "light" | "dark";
+
 const ThemeProvider: React.FC<{
   children: React.ReactNode;
 }> = ({ children }) => {
-  const [theme, setTheme] = useLocalStorage<string>("theme", "dark");
+  const [theme, setTheme] = useLocalStorage<Theme>("theme", "dark");
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bc5502a and ad2c61b.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (11)
  • web/package.json (2 hunks)
  • web/src/app.tsx (3 hunks)
  • web/src/context/StyledComponentsProvider.tsx (0 hunks)
  • web/src/context/ThemeProvider.tsx (1 hunks)
  • web/src/global.css (1 hunks)
  • web/src/styles/commonStyles.ts (0 hunks)
  • web/src/styles/customScrollbar.ts (0 hunks)
  • web/src/styles/global-style.ts (0 hunks)
  • web/src/styles/landscapeStyle.ts (0 hunks)
  • web/src/styles/themes.ts (0 hunks)
  • web/vite.config.js (2 hunks)
💤 Files with no reviewable changes (6)
  • web/src/styles/global-style.ts
  • web/src/styles/landscapeStyle.ts
  • web/src/styles/themes.ts
  • web/src/styles/commonStyles.ts
  • web/src/styles/customScrollbar.ts
  • web/src/context/StyledComponentsProvider.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Redirect rules - curate-v2
  • GitHub Check: Header rules - curate-v2
  • GitHub Check: Pages changed - curate-v2
🔇 Additional comments (6)
web/vite.config.js (1)

5-5: LGTM! Tailwind v4 Vite integration is correct.

The Tailwind CSS integration follows the standard pattern for v4 with Vite using the @tailwindcss/vite plugin.

Also applies to: 32-32

web/src/global.css (1)

1-20: LGTM! Tailwind v4 @theme directive and imports are correctly structured.

The global CSS setup follows Tailwind v4 best practices: importing the UI library theme, importing Tailwind, and defining custom design tokens via the @theme directive. The token definitions are comprehensive and well-organized.

web/package.json (2)

78-78: LGTM! Tailwind CSS dependencies are correctly added.

Both tailwindcss and @tailwindcss/vite are on the same version (4.1.16), which ensures consistency. The @tailwindcss/vite package is appropriately placed in both dependencies and devDependencies for build tooling access.

Also applies to: 107-107


73-73: Manually verify component compatibility after Tailwind migration to v3.6.0.

The upgrade to v3.6.0 involved a major migration from styled-components to Tailwind CSS. The library was migrated to Tailwind CSS, which includes changes to component styling and theming. Tailwind is already configured in the project (v4.1.16).

The codebase uses 23+ components from the library across 40+ files, including several internal components prefixed with underscore (_TimelineItem1, _IItem1). However, no public changelog documents specific breaking changes and component API modifications for v3.6.0.

Actions required:

  • Test all component usages throughout the application (run tests and manual QA)
  • Verify visual regressions from CSS token/spacing changes
  • Confirm internal components (_TimelineItem1, _IItem1) remain stable and exported in v3
  • Check for any prop renames or removed component APIs against the library's Storybook or GitHub repository
web/src/context/ThemeProvider.tsx (1)

10-22: LGTM! Dark mode implementation is correct.

The theme toggling logic and the useEffect that applies the dark class to document.documentElement correctly implements Tailwind's class-based dark mode strategy. The implementation will work seamlessly with Tailwind's dark: variant.

web/src/app.tsx (1)

4-4: LGTM! Theme provider migration is correctly implemented.

The migration from StyledComponentsProvider to the new ThemeProvider is clean and correct. The global.css import is properly placed early in the file, and the ThemeProvider correctly wraps the entire application as the outermost provider to ensure theme context is available throughout the component tree.

Also applies to: 7-7, 26-26, 59-59

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
web/src/context/Web3Provider.tsx (1)

62-62: Consider adding the brand color to the theme system for maintainability.

The hardcoded color #4D00B4 is correct—it matches the primary brand color used throughout SVG assets. However, since the codebase has migrated to Tailwind with a theme system (defined in web/src/global.css), consider adding this color to the @theme block for consistency and easier maintenance:

/* In web/src/global.css @theme block */
--color-primary: #4D00B4;

Then reference it in Web3Provider:

"--w3m-color-mix": "var(--color-primary)",

This keeps brand colors centralized and easier to maintain across the codebase. The color itself doesn't need to change between light/dark modes—this is a brand constant, not a theme-dependent color.

web/src/layout/index.tsx (1)

22-22: Consider extracting the hardcoded spacing value.

The hardcoded pt-[70px] value appears to offset the ToastContainer from the header. For better maintainability and theme consistency, consider defining this as a CSS variable or Tailwind theme extension that matches the header height.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ad2c61b and d2d2579.

📒 Files selected for processing (3)
  • web/global.d.ts (1 hunks)
  • web/src/context/Web3Provider.tsx (1 hunks)
  • web/src/layout/index.tsx (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Redirect rules - curate-v2
  • GitHub Check: Header rules - curate-v2
  • GitHub Check: Pages changed - curate-v2
🔇 Additional comments (2)
web/src/layout/index.tsx (1)

23-23: Consider adding dark mode variant.

The background class bg-klerosUIComponentsLightBackground implies a light theme background. Based on the PR's ThemeProvider that toggles a document-level dark class, consider whether this element needs a corresponding dark mode variant (e.g., dark:bg-klerosUIComponentsDarkBackground).

web/global.d.ts (1)

1-12: LGTM!

The removal of styled-components module augmentation is appropriate for the Tailwind migration. The file correctly preserves the necessary ambient declarations for SVG and PNG imports while maintaining proper module structure with the export {} statement.

@kleros kleros deleted a comment from coderabbitai bot Oct 24, 2025
@kleros kleros deleted a comment from coderabbitai bot Oct 24, 2025
coderabbitai[bot]
coderabbitai bot previously approved these changes Oct 30, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 20

🧹 Nitpick comments (3)
web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/FormContact.tsx (1)

45-45: Consider using standard spacing scale instead of arbitrary value.

The arbitrary value mb-[10px] works correctly in Tailwind v4, but using the standard spacing scale improves consistency across the codebase. Since 10px equals 2.5rem (2.5 × 4px), consider using mb-2.5 instead.

-      <label className="flex justify-between mb-[10px]">{contactLabel}</label>
+      <label className="flex justify-between mb-2.5">{contactLabel}</label>
web/src/layout/Header/Logo.tsx (2)

8-13: Remove unnecessary whitespace literal.

The {" "} on line 9 serves no purpose and can be removed for cleaner code.

Apply this diff:

  <div className="flex flex-row items-center gap-4">
-    {" "}
    <Link to={"/"}>
      <CurateLogo className="transition duration-100 max-h-12 w-auto hover:fill-white/75" />
    </Link>
  </div>

10-12: Add accessible label for the logo link.

The logo link lacks descriptive text for screen readers. Add an aria-label to improve accessibility.

Apply this diff:

-    <Link to={"/"}>
+    <Link to={"/"} aria-label="Home">
      <CurateLogo className="transition duration-100 max-h-12 w-auto hover:fill-white/75" />
    </Link>
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f638cb8 and bb0901b.

📒 Files selected for processing (23)
  • web/src/app.tsx (3 hunks)
  • web/src/components/ConnectWallet/AccountDisplay.tsx (2 hunks)
  • web/src/components/InfoCard.tsx (1 hunks)
  • web/src/components/LightButton.tsx (1 hunks)
  • web/src/components/Overlay.tsx (1 hunks)
  • web/src/components/OverlayPortal.tsx (1 hunks)
  • web/src/context/ThemeProvider.tsx (1 hunks)
  • web/src/global.css (1 hunks)
  • web/src/layout/Header/DesktopHeader.tsx (1 hunks)
  • web/src/layout/Header/Logo.tsx (1 hunks)
  • web/src/layout/Header/index.tsx (1 hunks)
  • web/src/layout/Header/navbar/DappList.tsx (1 hunks)
  • web/src/layout/Header/navbar/Debug.tsx (2 hunks)
  • web/src/layout/Header/navbar/Explore.tsx (2 hunks)
  • web/src/layout/Header/navbar/Menu/Help.tsx (1 hunks)
  • web/src/layout/Header/navbar/Menu/Settings/General.tsx (1 hunks)
  • web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/EmailVerificationInfo.tsx (1 hunks)
  • web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/FormContact.tsx (1 hunks)
  • web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx (3 hunks)
  • web/src/layout/Header/navbar/Menu/Settings/Notifications/index.tsx (1 hunks)
  • web/src/layout/Header/navbar/Menu/Settings/index.tsx (1 hunks)
  • web/src/layout/Header/navbar/Menu/index.tsx (1 hunks)
  • web/src/layout/Header/navbar/Product.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • web/src/context/ThemeProvider.tsx
  • web/src/app.tsx
🧰 Additional context used
🧠 Learnings (8)
📓 Common learnings
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/index.tsx:15-28
Timestamp: 2025-10-24T21:25:59.174Z
Learning: In Tailwind v4, when using CSS variables from external libraries like kleros/ui-components-library, add the `source` directive in global.css to tell Tailwind to scan and generate utility classes from those variables. Example: `source "../node_modules/kleros/ui-components-library";`
📚 Learning: 2024-11-04T13:31:54.080Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx:72-96
Timestamp: 2024-11-04T13:31:54.080Z
Learning: In the React TypeScript component `FormContactDetails` in `web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx`, error handling and user feedback are implemented within the `addUser` and `updateEmail` functions, which display toasts to the user.

Applied to files:

  • web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/FormContact.tsx
  • web/src/layout/Header/navbar/Menu/Settings/index.tsx
  • web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/EmailVerificationInfo.tsx
  • web/src/layout/Header/navbar/Menu/Settings/Notifications/index.tsx
  • web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx
📚 Learning: 2024-11-04T13:41:31.226Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx:126-126
Timestamp: 2024-11-04T13:41:31.226Z
Learning: In `web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx`, the `isUndefined` function effectively handles `null` or `undefined` values. Therefore, using the non-null assertion `!` on `user?.emailUpdateableAt` when calling `timeLeftUntil(user?.emailUpdateableAt!)` is acceptable, as potential `null` or `undefined` cases are already managed.

Applied to files:

  • web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/FormContact.tsx
  • web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/EmailVerificationInfo.tsx
  • web/src/layout/Header/navbar/Menu/Settings/Notifications/index.tsx
  • web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx
📚 Learning: 2024-11-04T13:33:39.755Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/pages/Settings/index.tsx:18-26
Timestamp: 2024-11-04T13:33:39.755Z
Learning: In `web/src/pages/Settings/index.tsx`, the parent route handles the default `/settings` route, error boundaries, and loading states, so it's not necessary to include them in this component.

Applied to files:

  • web/src/layout/Header/navbar/Menu/Settings/index.tsx
  • web/src/layout/Header/navbar/Menu/Settings/Notifications/index.tsx
📚 Learning: 2024-11-04T13:39:19.748Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/utils/atlas/updateEmail.ts:21-38
Timestamp: 2024-11-04T13:39:19.748Z
Learning: For the `updateEmail` function in `web/src/utils/atlas/updateEmail.ts`, input validation and error handling are performed in the component that utilizes it. Therefore, additional checks within this utility function are unnecessary.

Applied to files:

  • web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/EmailVerificationInfo.tsx
📚 Learning: 2024-11-04T13:34:45.425Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/utils/atlas/confirmEmail.ts:24-36
Timestamp: 2024-11-04T13:34:45.425Z
Learning: In the `confirmEmail` function in `web/src/utils/atlas/confirmEmail.ts`, input validation for the address is performed in the calling component, and additional checks are done in the API call itself. Input validation does not need to be repeated in this function.

Applied to files:

  • web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/EmailVerificationInfo.tsx
📚 Learning: 2024-11-04T13:29:55.971Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/context/AtlasProvider.tsx:176-193
Timestamp: 2024-11-04T13:29:55.971Z
Learning: In the `web/src/context/AtlasProvider.tsx` file of the React application, the `authoriseUser` function handles session invalidation and delegates error handling and user notifications to the functions that invoke it. Therefore, adding error notifications within `authoriseUser` is unnecessary.

Applied to files:

  • web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/EmailVerificationInfo.tsx
  • web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx
📚 Learning: 2025-10-24T21:25:59.174Z
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/index.tsx:15-28
Timestamp: 2025-10-24T21:25:59.174Z
Learning: In Tailwind v4, when using CSS variables from external libraries like kleros/ui-components-library, add the `source` directive in global.css to tell Tailwind to scan and generate utility classes from those variables. Example: `source "../node_modules/kleros/ui-components-library";`

Applied to files:

  • web/src/global.css
🧬 Code graph analysis (5)
web/src/layout/Header/navbar/Debug.tsx (1)
web/src/consts/index.ts (2)
  • RELEASE_VERSION (12-12)
  • GIT_URL (11-11)
web/src/layout/Header/navbar/Menu/Settings/General.tsx (2)
web/src/components/EnsureChain.tsx (1)
  • EnsureChain (10-14)
web/src/components/ConnectWallet/AccountDisplay.tsx (3)
  • IdenticonOrAvatar (16-34)
  • AddressOrName (40-50)
  • ChainDisplay (52-56)
web/src/layout/Header/navbar/Menu/Settings/Notifications/index.tsx (2)
web/src/layout/Header/navbar/index.tsx (1)
  • ISettings (54-56)
web/src/components/EnsureChain.tsx (1)
  • EnsureChain (10-14)
web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx (1)
web/src/utils/date.ts (1)
  • timeLeftUntil (43-69)
web/src/layout/Header/index.tsx (1)
web/src/utils/getGraphqlUrl.ts (1)
  • getGraphqlUrl (3-7)
🔇 Additional comments (12)
web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/FormContact.tsx (1)

45-52: Migration looks clean, but verify label-input association for accessibility.

The migration from styled-components to Tailwind classes is well-executed. However, the <label> on line 45 lacks a htmlFor attribute to associate it with the input field. If the Field component renders an input element, ensure proper label-input association for accessibility.

Consider adding a htmlFor attribute if the Field component exposes an id:

-      <label className="flex justify-between mb-[10px]">{contactLabel}</label>
+      <label htmlFor="contact-input" className="flex justify-between mb-[10px]">{contactLabel}</label>
       <Field
         className="flex flex-col items-center w-full"
+        id="contact-input"
         variant={fieldVariant}

Alternatively, if the Field component from @kleros/ui-components-library handles accessibility internally or doesn't support id props, you may disregard this suggestion.

web/src/layout/Header/navbar/DappList.tsx (1)

98-98: LGTM!

The h1 header uses standard Tailwind utility classes correctly.

web/src/layout/Header/navbar/Menu/Help.tsx (1)

52-53: The breakpoint is already properly configured—no action needed.

The custom landscape-900: breakpoint is correctly defined in web/src/global.css using Tailwind v4's @theme block with the --breakpoint-landscape-900: 900px; variable, which automatically creates the responsive modifier. The review comment incorrectly assumes traditional Tailwind configuration (JS/TS config file), which is not applicable to Tailwind v4's CSS-first approach. The code at lines 52-53 in Help.tsx correctly uses this pre-configured breakpoint.

Likely an incorrect or invalid review comment.

web/src/layout/Header/navbar/Debug.tsx (1)

5-20: LGTM!

The migration from styled-components to className-based styling is implemented correctly. The arbitrary font-family syntax font-[Roboto_Mono,monospace] is proper Tailwind v4 usage.

web/src/components/Overlay.tsx (1)

1-5: LGTM!

Clean conversion from styled-component to a functional component with Tailwind classes. The bg-black-low-opacity custom color should be defined in your theme configuration.

web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/EmailVerificationInfo.tsx (1)

36-49: LGTM!

Successful migration from styled-components to utility classes. The SVG fill and layout classes are properly applied.

web/src/global.css (2)

1-67: Well-structured Tailwind v4 integration.

The global stylesheet properly:

  • Imports the UI library theme and Tailwind v4 using the new @import syntax
  • Defines custom theme tokens via @theme directive
  • Implements accessible focus management with :focus-visible (addressing the previous review concern)

The focus styling (lines 60-67) now correctly preserves keyboard navigation accessibility while removing focus outlines for mouse users.


138-142: Verify browser support for CSS nesting.

The nested selector syntax ul { li { ... } } requires modern browsers. Based on your Tailwind v4 adoption (which targets Chrome 111+, Safari 16.4+, Firefox 128+), this should be supported, but confirm this aligns with your browser compatibility requirements.

web/src/layout/Header/index.tsx (1)

12-33: LGTM! Clean migration to Tailwind v4 syntax.

The header structure correctly uses Tailwind v4 features including advanced selector syntax for StatusBanner styling and CSS variables for theme integration. The sticky positioning and backdrop blur effects are properly configured.

web/src/layout/Header/navbar/Menu/Settings/General.tsx (1)

20-49: LGTM! Proper use of Tailwind v4 advanced features.

The component correctly uses Tailwind v4's advanced selector syntax ([&>label], [&_label]) and pseudo-element utilities (before:content-['']) to style nested elements. The layout structure is clean and maintains the original functionality.

web/src/layout/Header/DesktopHeader.tsx (1)

43-43: LGTM! Correct Tailwind v4 important modifier syntax.

The important modifier is correctly placed at the end of the utility class (fill-white!), which is the proper Tailwind v4 syntax.

web/src/layout/Header/navbar/Menu/Settings/Notifications/index.tsx (1)

18-30: LGTM!

The migration to Tailwind utilities is well-executed. The flexbox layout structure correctly preserves the component's intended design with proper centering and spacing.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

♻️ Duplicate comments (1)
web/src/components/ConnectWallet/AccountDisplay.tsx (1)

78-80: Fix merged utility class separator.

The concatenated strings still miss a trailing space before landscape-900:hidden, so the output becomes before:ml-[3px]landscape-900:hidden and Tailwind drops both utilities. Add the separator (or switch to a template literal) so each class stays intact.

-          "before:content-[''] before:w-2 before:h-2 before:rounded-[50%] before:bg-klerosUIComponentsSuccess before:my-0 before:mr-[13px] before:ml-[3px]" +
+          "before:content-[''] before:w-2 before:h-2 before:rounded-[50%] before:bg-klerosUIComponentsSuccess before:my-0 before:mr-[13px] before:ml-[3px] " +
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bb0901b and 318211a.

📒 Files selected for processing (13)
  • web/src/components/ConnectWallet/AccountDisplay.tsx (2 hunks)
  • web/src/components/InfoCard.tsx (1 hunks)
  • web/src/components/LightButton.tsx (1 hunks)
  • web/src/global.css (1 hunks)
  • web/src/layout/Header/DesktopHeader.tsx (1 hunks)
  • web/src/layout/Header/Logo.tsx (1 hunks)
  • web/src/layout/Header/navbar/DappList.tsx (1 hunks)
  • web/src/layout/Header/navbar/Explore.tsx (2 hunks)
  • web/src/layout/Header/navbar/Menu/Help.tsx (1 hunks)
  • web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx (3 hunks)
  • web/src/layout/Header/navbar/Menu/Settings/index.tsx (1 hunks)
  • web/src/layout/Header/navbar/Menu/index.tsx (1 hunks)
  • web/src/layout/Header/navbar/Product.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
  • web/src/components/InfoCard.tsx
  • web/src/layout/Header/navbar/Explore.tsx
  • web/src/layout/Header/Logo.tsx
  • web/src/components/LightButton.tsx
  • web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/index.tsx:15-28
Timestamp: 2025-10-24T21:25:59.174Z
Learning: In Tailwind v4, when using CSS variables from external libraries like kleros/ui-components-library, add the `source` directive in global.css to tell Tailwind to scan and generate utility classes from those variables. Example: `source "../node_modules/kleros/ui-components-library";`
📚 Learning: 2025-10-24T21:25:59.174Z
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/index.tsx:15-28
Timestamp: 2025-10-24T21:25:59.174Z
Learning: In Tailwind v4, when using CSS variables from external libraries like kleros/ui-components-library, add the `source` directive in global.css to tell Tailwind to scan and generate utility classes from those variables. Example: `source "../node_modules/kleros/ui-components-library";`

Applied to files:

  • web/src/global.css
📚 Learning: 2024-11-04T13:33:39.755Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/pages/Settings/index.tsx:18-26
Timestamp: 2024-11-04T13:33:39.755Z
Learning: In `web/src/pages/Settings/index.tsx`, the parent route handles the default `/settings` route, error boundaries, and loading states, so it's not necessary to include them in this component.

Applied to files:

  • web/src/layout/Header/navbar/Menu/Settings/index.tsx
📚 Learning: 2024-11-04T13:31:54.080Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx:72-96
Timestamp: 2024-11-04T13:31:54.080Z
Learning: In the React TypeScript component `FormContactDetails` in `web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx`, error handling and user feedback are implemented within the `addUser` and `updateEmail` functions, which display toasts to the user.

Applied to files:

  • web/src/layout/Header/navbar/Menu/Settings/index.tsx
📚 Learning: 2024-11-04T13:41:31.226Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx:126-126
Timestamp: 2024-11-04T13:41:31.226Z
Learning: In `web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx`, the `isUndefined` function effectively handles `null` or `undefined` values. Therefore, using the non-null assertion `!` on `user?.emailUpdateableAt` when calling `timeLeftUntil(user?.emailUpdateableAt!)` is acceptable, as potential `null` or `undefined` cases are already managed.

Applied to files:

  • web/src/layout/Header/navbar/Menu/Settings/index.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Redirect rules - curate-v2
  • GitHub Check: Header rules - curate-v2
  • GitHub Check: Pages changed - curate-v2
🔇 Additional comments (2)
web/src/layout/Header/navbar/Menu/Help.tsx (1)

48-69: LGTM! Previous issues resolved.

The Tailwind utility classes are now correct, and the className concatenation includes proper spacing.

web/src/layout/Header/navbar/Menu/Settings/index.tsx (1)

39-39: Previous issues resolved.

The invalid width-[calc(...)] utility has been corrected to w-[calc(...)].

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (1)
web/src/layout/Header/navbar/Product.tsx (1)

39-39: Consider removing unnecessary flex class.

The <small> element contains only text and uses text-center for alignment. The flex class appears unnecessary since text-center alone handles text alignment for inline content.

-      <small className="flex font-normal text-center leading-[19px]">{text}</small>
+      <small className="font-normal text-center leading-[19px]">{text}</small>
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 318211a and dba15bb.

📒 Files selected for processing (7)
  • web/src/components/LightButton.tsx (1 hunks)
  • web/src/layout/Header/navbar/DappList.tsx (1 hunks)
  • web/src/layout/Header/navbar/Explore.tsx (2 hunks)
  • web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx (3 hunks)
  • web/src/layout/Header/navbar/Menu/Settings/index.tsx (1 hunks)
  • web/src/layout/Header/navbar/Menu/index.tsx (1 hunks)
  • web/src/layout/Header/navbar/Product.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • web/src/layout/Header/navbar/DappList.tsx
  • web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx
  • web/src/components/LightButton.tsx
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/index.tsx:15-28
Timestamp: 2025-10-24T21:25:59.174Z
Learning: In Tailwind v4, when using CSS variables from external libraries like kleros/ui-components-library, add the `source` directive in global.css to tell Tailwind to scan and generate utility classes from those variables. Example: `source "../node_modules/kleros/ui-components-library";`
📚 Learning: 2024-11-04T13:33:39.755Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/pages/Settings/index.tsx:18-26
Timestamp: 2024-11-04T13:33:39.755Z
Learning: In `web/src/pages/Settings/index.tsx`, the parent route handles the default `/settings` route, error boundaries, and loading states, so it's not necessary to include them in this component.

Applied to files:

  • web/src/layout/Header/navbar/Menu/Settings/index.tsx
📚 Learning: 2024-11-04T13:31:54.080Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx:72-96
Timestamp: 2024-11-04T13:31:54.080Z
Learning: In the React TypeScript component `FormContactDetails` in `web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx`, error handling and user feedback are implemented within the `addUser` and `updateEmail` functions, which display toasts to the user.

Applied to files:

  • web/src/layout/Header/navbar/Menu/Settings/index.tsx
📚 Learning: 2024-11-04T13:41:31.226Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx:126-126
Timestamp: 2024-11-04T13:41:31.226Z
Learning: In `web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx`, the `isUndefined` function effectively handles `null` or `undefined` values. Therefore, using the non-null assertion `!` on `user?.emailUpdateableAt` when calling `timeLeftUntil(user?.emailUpdateableAt!)` is acceptable, as potential `null` or `undefined` cases are already managed.

Applied to files:

  • web/src/layout/Header/navbar/Menu/Settings/index.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Redirect rules - curate-v2
  • GitHub Check: Header rules - curate-v2
  • GitHub Check: Pages changed - curate-v2
🔇 Additional comments (4)
web/src/layout/Header/navbar/Explore.tsx (2)

17-18: LGTM! Clean active route detection.

The isActive helper correctly handles both the root path (exact match) and nested routes (first segment comparison), which prevents false positives in navigation highlighting.


36-49: Custom utilities are properly configured—no changes required, but consider adding @source directive.

The className structure is correct and all custom utilities are properly defined in your Tailwind v4 setup:

  • text-klerosUIComponentsPrimaryText, text-primary-text-73, text-white-73 are configured via CSS variables in the @theme block
  • landscape-900: breakpoint is defined as --breakpoint-landscape-900: 900px
  • All utilities are actively used and functional throughout the codebase

Based on the learning context, consider adding the @source directive in web/src/global.css to explicitly tell Tailwind to scan the @kleros/ui-components-library for utility classes:

@source "../node_modules/@kleros/ui-components-library";
@import "@kleros/ui-components-library/theme.css";
@import "tailwindcss";

This ensures Tailwind can generate utilities from CSS variables in the external library, though the current setup appears to be working without it.

web/src/layout/Header/navbar/Product.tsx (1)

16-25: Previous critical issues successfully resolved!

All three issues from the previous review have been properly addressed:

  1. ✅ Security: rel="noopener noreferrer" added
  2. ✅ Styling: className construction fixed and dynamic width moved to style prop
  3. ✅ This segment demonstrates proper Tailwind v4 migration pattern
web/src/layout/Header/navbar/Menu/index.tsx (1)

37-37: Clean responsive layout structure.

The flex layout with responsive breakpoint is well-structured for converting the menu from vertical to horizontal orientation.

coderabbitai[bot]
coderabbitai bot previously approved these changes Oct 31, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
web/src/layout/Header/navbar/index.tsx (1)

2-2: Remove unused styled-components import.

The styled import is no longer used after migrating to Tailwind utility classes.

Apply this diff to remove the unused import:

-import styled from "styled-components";
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dba15bb and f3b7df3.

📒 Files selected for processing (3)
  • web/src/layout/Header/MobileHeader.tsx (1 hunks)
  • web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/FormContact.tsx (2 hunks)
  • web/src/layout/Header/navbar/index.tsx (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/FormContact.tsx
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/index.tsx:15-28
Timestamp: 2025-10-24T21:25:59.174Z
Learning: In Tailwind v4, when using CSS variables from external libraries like kleros/ui-components-library, add the `source` directive in global.css to tell Tailwind to scan and generate utility classes from those variables. Example: `source "../node_modules/kleros/ui-components-library";`
🧬 Code graph analysis (1)
web/src/layout/Header/navbar/index.tsx (1)
web/src/layout/Header/navbar/Menu/Settings/General.tsx (1)
  • DisconnectWalletButton (7-10)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Redirect rules - curate-v2
  • GitHub Check: Header rules - curate-v2
  • GitHub Check: Pages changed - curate-v2
🔇 Additional comments (2)
web/src/layout/Header/navbar/index.tsx (1)

59-66: LGTM! Wallet container refactoring is correct.

The replacement of styled components with Tailwind flex utilities is appropriate, and the wrapper div for vertical alignment maintains the intended layout.

web/src/layout/Header/MobileHeader.tsx (1)

29-29: Custom breakpoint is properly configured.

The landscape-900 breakpoint is defined as a CSS variable in web/src/global.css (line 21: --breakpoint-landscape-900: 900px;) and is successfully used across the codebase in multiple files (DesktopHeader, DappList, Explore, Menu, Settings, LightButton, AccountDisplay). The consistent usage throughout the project confirms proper Tailwind integration.

However, the icon-only button on line 33 lacks accessibility attributes — add aria-label or title to the LightButton since text="":

<LightButton className="p-0 [&_.button-svg]:mr-0" text="" Icon={HamburgerIcon} onClick={toggleIsOpen} aria-label="Toggle menu" />

coderabbitai[bot]
coderabbitai bot previously approved these changes Oct 31, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (4)
web/src/components/InformationCards/RegistryInformationCard/TopInfo.tsx (2)

45-52: Consider removing redundant bottom margin.

The mb-2 class on the image may be redundant since the parent container at line 40 already uses gap-4 for spacing between flex items.

             <img
               width={125}
               height={125}
-              className="object-contain mb-2"
+              className="object-contain"
               src={imageSrc}
               onError={() => setImageSrc(getIpfsUrl(DEFAULT_LIST_LOGO))}
               alt="List Img"
             />

42-42: Maintain consistency with image styling.

If you remove the mb-2 from the image element (see previous comment), ensure the Skeleton placeholder matches the same styling for visual consistency.

-            <Skeleton width={125} height={125} borderRadius="62.5px" className="mb-2" />
+            <Skeleton width={125} height={125} borderRadius="62.5px" />
web/src/pages/AllLists/RegistryDetails/Tabs.tsx (2)

18-18: Clarify the necessity of content: null fields.

Both TABS entries include content: null, but the current implementation uses a callback-based approach for tab changes (line 58) rather than rendering tab content directly. If the content property is not required by the TabsComponent API, these fields add unnecessary noise.

Please confirm whether the content property is required by @kleros/ui-components-library v3.6.0's TabsComponent. The same web search from the previous comment will help verify this.

Also applies to: 27-27


54-60: Clean callback-based tab implementation.

The refactored TabsComponent usage correctly implements callback-based navigation. The callback signature ignoring the first parameter with _ is appropriate, and the integration with handleTabChange maintains the existing navigation behavior.

Consider adding TypeScript typing for the TABS array to improve type safety and make the expected structure more explicit:

+interface TabItem {
+  id: number;
+  text: string;
+  value: number;
+  Icon: React.FC;
+  path: string;
+  identifier: string;
+  content: null | React.ReactNode;
+}
+
-const TABS = [
+const TABS: TabItem[] = [
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ef19a2c and 0e99882.

📒 Files selected for processing (5)
  • web/src/components/InformationCards/RegistryInformationCard/TopInfo.tsx (1 hunks)
  • web/src/components/InformationCards/RegistryInformationCard/index.tsx (4 hunks)
  • web/src/pages/AllLists/RegistryDetails/Tabs.tsx (2 hunks)
  • web/src/pages/AllLists/RegistryDetails/index.tsx (2 hunks)
  • web/src/pages/AllLists/index.tsx (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • web/src/pages/AllLists/index.tsx
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/styles/breakpoints.ts:1-1
Timestamp: 2025-11-14T22:12:39.974Z
Learning: In the kleros/curate-v2 repository, the kleros/ui-components-library overrides Tailwind's lg breakpoint to 900px (not the default 1024px). The LG_BREAKPOINT constant in web/src/styles/breakpoints.ts is set to 900 to match this override. This configuration is imported via the source directive in global.css.
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/index.tsx:15-28
Timestamp: 2025-10-24T21:25:59.174Z
Learning: In Tailwind v4, when using CSS variables from external libraries like kleros/ui-components-library, add the `source` directive in global.css to tell Tailwind to scan and generate utility classes from those variables. Example: `source "../node_modules/kleros/ui-components-library";`
📚 Learning: 2024-11-04T13:33:39.755Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/pages/Settings/index.tsx:18-26
Timestamp: 2024-11-04T13:33:39.755Z
Learning: In `web/src/pages/Settings/index.tsx`, the parent route handles the default `/settings` route, error boundaries, and loading states, so it's not necessary to include them in this component.

Applied to files:

  • web/src/pages/AllLists/RegistryDetails/Tabs.tsx
🧬 Code graph analysis (3)
web/src/pages/AllLists/RegistryDetails/Tabs.tsx (2)
web/src/utils/uri.ts (1)
  • encodeListURIFilter (4-10)
web/src/consts/filters.ts (1)
  • List_filters (5-11)
web/src/components/InformationCards/RegistryInformationCard/TopInfo.tsx (4)
web/src/utils/index.ts (1)
  • isUndefined (5-5)
web/src/utils/getIpfsUrl.ts (1)
  • getIpfsUrl (4-8)
web/src/consts/index.ts (1)
  • DEFAULT_LIST_LOGO (23-23)
web/src/consts/chains.ts (1)
  • SUPPORTED_CHAINS (9-11)
web/src/components/InformationCards/RegistryInformationCard/index.tsx (2)
web/src/utils/index.ts (1)
  • cn (44-46)
web/src/components/InformationCards/RegistryInformationCard/Policies.tsx (1)
  • Policies (21-59)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Redirect rules - curate-v2
  • GitHub Check: Header rules - curate-v2
  • GitHub Check: Pages changed - curate-v2
🔇 Additional comments (12)
web/src/pages/AllLists/RegistryDetails/index.tsx (1)

45-69: LGTM! Clean migration to Tailwind.

The replacement of the styled Container with a div using flex flex-col is correct and follows standard Tailwind patterns for vertical layouts. The change is purely structural with no impact on functionality.

web/src/components/InformationCards/RegistryInformationCard/TopInfo.tsx (3)

35-38: LGTM: Responsive flex layout implemented correctly.

The combination of flex-wrap with lg:flex-nowrap ensures proper responsive behavior, and the responsive padding using responsiveSize maintains consistency with the existing codebase patterns.


63-66: LGTM: Breakpoint aligns with library configuration.

The responsiveSize(24, 32, 900) correctly uses 900px to match the LG_BREAKPOINT override from @kleros/ui-components-library.

Based on learnings


69-76: LGTM: Anchor styling correctly applied.

The text-klerosUIComponentsPrimaryBlue utility class properly styles the link, and the structure within the Copiable component is maintained correctly.

web/src/components/InformationCards/RegistryInformationCard/index.tsx (5)

11-11: LGTM: Correct usage of cn utility for className composition.

The cn utility is properly imported and used to merge the optional className prop with base classes, allowing for flexible external styling while maintaining core styles.

Also applies to: 51-51


30-30: LGTM: Public API extended appropriately.

Adding the optional className prop enables flexible external styling, which is a standard pattern for utility-class-based component libraries.


53-55: LGTM: Warning message correctly styled.

The warning paragraph uses appropriate utility classes and theme-aware CSS variables for consistent styling. The conditional rendering based on validation results is correctly implemented.


69-72: LGTM: Divider correctly implemented.

The hr element with h-px and border-none properly replaces the styled Divider component. The responsive margin logic using responsiveSize maintains consistency with the rest of the codebase.


73-88: LGTM: Bottom section layout correctly structured.

The flex-based layout with flex-wrap and justify-between provides appropriate responsive behavior. The nested structure maintains logical grouping of the submitter information and action button.

web/src/pages/AllLists/RegistryDetails/Tabs.tsx (3)

8-8: LGTM: clsx import aligns with Tailwind migration.

The addition of clsx is appropriate for composing className strings in the Tailwind-based approach.


56-56: Verify the complex Tailwind selector behaves as intended.

The className includes *:[&_svg]:mr-2, which is a complex selector attempting to add right margin to SVG elements within direct children. While this syntax is valid in Tailwind, it's worth verifying that it produces the desired spacing for tab icons.

If this doesn't work as expected, consider using a simpler approach by adding the margin class directly to the Icon components within each tab item, or verify the rendered output to ensure proper icon spacing.


12-12: Verify if both id and value fields are necessary.

Both TABS entries now include id and value fields with identical values (0 and 1 respectively). This appears redundant and could cause confusion about which field should be used for tab identification.

Please verify whether the @kleros/ui-components-library v3 TabsComponent requires both fields. If only one is needed, consider removing the redundant field:

Also applies to: 21-21

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
web/src/components/InformationCards/RegistryInformationCard/TopInfo.tsx (1)

63-66: Consider consolidating gap utilities for clarity.

The gap-8 class on line 64 sets both row and column gaps to 32px, but line 65's inline columnGap style overrides it with responsive values. While this works, mixing Tailwind utilities with inline styles for the same property can be confusing for maintainability.

If the responsiveSize function provides custom interpolation that Tailwind's responsive utilities don't support, this is acceptable. Otherwise, consider using Tailwind's responsive gap utilities (e.g., gap-6 lg:gap-8) for consistency.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0e99882 and 81b91e2.

📒 Files selected for processing (1)
  • web/src/components/InformationCards/RegistryInformationCard/TopInfo.tsx (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/styles/breakpoints.ts:1-1
Timestamp: 2025-11-14T22:12:39.974Z
Learning: In the kleros/curate-v2 repository, the kleros/ui-components-library overrides Tailwind's lg breakpoint to 900px (not the default 1024px). The LG_BREAKPOINT constant in web/src/styles/breakpoints.ts is set to 900 to match this override. This configuration is imported via the source directive in global.css.
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/index.tsx:15-28
Timestamp: 2025-10-24T21:25:59.174Z
Learning: In Tailwind v4, when using CSS variables from external libraries like kleros/ui-components-library, add the `source` directive in global.css to tell Tailwind to scan and generate utility classes from those variables. Example: `source "../node_modules/kleros/ui-components-library";`
🧬 Code graph analysis (1)
web/src/components/InformationCards/RegistryInformationCard/TopInfo.tsx (4)
web/src/utils/index.ts (1)
  • isUndefined (5-5)
web/src/utils/getIpfsUrl.ts (1)
  • getIpfsUrl (4-8)
web/src/consts/index.ts (1)
  • DEFAULT_LIST_LOGO (23-23)
web/src/consts/chains.ts (1)
  • SUPPORTED_CHAINS (9-11)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Redirect rules - curate-v2
  • GitHub Check: Header rules - curate-v2
  • GitHub Check: Pages changed - curate-v2
🔇 Additional comments (2)
web/src/components/InformationCards/RegistryInformationCard/TopInfo.tsx (2)

35-62: Successful migration to Tailwind utilities.

The layout structure and conditional rendering with loading skeletons look correct. The image properly uses object-contain for aspect ratio preservation, and all elements use appropriate Tailwind utility classes. Good job addressing the previous review feedback—the paragraph element (line 60) no longer has the unnecessary underline utilities.


69-76: Anchor styling is correct.

The anchor element appropriately uses no-underline hover:underline classes (unlike paragraph elements), and the external link properly includes rel="noreferrer" for security. The custom color class text-klerosUIComponentsPrimaryBlue correctly references the theme from @kleros/ui-components-library.

coderabbitai[bot]
coderabbitai bot previously approved these changes Nov 17, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
web/src/components/HistoryDisplay/index.tsx (1)

56-126: Fix the return type—function returns an array, not a single item.

The function signature declares the return type as TimelineItem (singular), but the function body creates and returns historyItems: TimelineItem[] (array) on line 125. The caller on line 30 spreads the result with acc.push(...history), confirming it expects an array. This type mismatch will cause TypeScript compilation errors.

Apply this diff to fix the return type:

 const constructItemsFromRequest = (
   request: RequestDetailsFragment,
   isLightTheme: boolean,
   isItem?: boolean
-): TimelineItem => {
+): TimelineItem[] => {
   const historyItems: TimelineItem[] = [];
🧹 Nitpick comments (6)
web/src/pages/AllLists/RegistryDetails/List/index.tsx (1)

59-63: Tailwind list container and Skeleton fallback look good; confirm justify-center matches desired layout

The new flex column wrapper and direct Skeleton usage preserve the list/skeleton behavior and look correct. One thing to double‑check: justify-center will vertically center the list items within the available height; if the previous ListContainer aligned items from the top, you may prefer dropping justify-center (or using justify-start) to avoid a subtle UX change.

web/src/pages/AllLists/RegistryDetails/ItemsDownloadLabel.tsx (2)

13-42: Add error handling for CSV conversion.

The json2csv conversion could potentially throw an error if the data is malformed. Consider wrapping the conversion in a try-catch block to handle errors gracefully.

  useEffect(() => {
    if (!items || !ref.current) return;
    setIsPreparing(true);
+   
+   try {
      const flattenedItems = items.map((item) => {
        const row = {
          id: item.id,
          status: item.status,
          disputed: item.disputed,
        };

        item.props.forEach((prop) => {
          row[`${prop.label} (${prop.description})`] = prop.value;
        });

        return row;
      });

      const csvData = json2csv(flattenedItems);
      const blob = new Blob([csvData], { type: "text/csv;charset=utf-8;" });
      const link = ref.current;

      if (link.download !== undefined) {
        const url = URL.createObjectURL(blob);
        link.setAttribute("href", url);
        link.setAttribute("download", `Kleros-Curate-${registryAddress}.csv`);
        link.click();
      }
+   } catch (error) {
+     console.error("Failed to generate CSV:", error);
+     // Optionally show user feedback
+   } finally {
+     setIsPreparing(false);
+   }
-   setIsPreparing(false);
  }, [items]);

37-42: Minor: Include registryAddress in dependency array.

The registryAddress prop is used within the effect (line 37) but is not included in the dependency array. While props are typically stable, for correctness and to satisfy ESLint's exhaustive-deps rule, consider adding it:

-  }, [items]);
+  }, [items, registryAddress]);
web/src/components/ItemCard/index.tsx (3)

9-10: Consider using cn consistently instead of mixing with clsx.

The cn utility wraps clsx with twMerge for better Tailwind class merging. Since you're already using cn on lines 31 and 40, consider using it consistently instead of clsx directly on line 50 to ensure proper class conflict resolution.

Apply this diff:

-import { cn } from "~src/utils";
-import clsx from "clsx";
+import { cn } from "~src/utils";

And on line 50:

-        <Button
-          className={clsx(
+        <Button
+          className={cn(

12-14: Consider adding comments to explain the responsive calculation logic.

The CSS calc formulas implement fluid sizing between 900px and 1250px breakpoints, but the intent isn't immediately clear. Adding brief comments would improve maintainability.

Example:

+// Fluid grid columns: scales from 1fr/150px/max-content to 1fr/180px/max-content between lg (900px) and xl (1250px)
 const landscapeGridColsCalc =
   "lg:grid-cols-[1fr_calc(150px+(180-150)*(min(max(100vw,900px),1250px)-900px)/(1250-900))_max-content]";
+// Fluid gap: scales from 16px to 36px between lg (900px) and xl (1250px)
 const landscapeGapCalc = "lg:gap-[calc(16px+(36-16)*(min(max(100vw,900px),1250px)-900px)/(1250-900))]";

37-37: Consider refactoring to use Tailwind consistently.

Mixing inline styles with Tailwind classes creates an inconsistent styling approach. If responsiveSize() is calculating dynamic column gaps, consider either incorporating it into the landscapeGapCalc constant or documenting why inline styles are necessary here.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 81b91e2 and cea5d0c.

📒 Files selected for processing (4)
  • web/src/components/HistoryDisplay/index.tsx (7 hunks)
  • web/src/components/ItemCard/index.tsx (2 hunks)
  • web/src/pages/AllLists/RegistryDetails/ItemsDownloadLabel.tsx (2 hunks)
  • web/src/pages/AllLists/RegistryDetails/List/index.tsx (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/styles/breakpoints.ts:1-1
Timestamp: 2025-11-14T22:12:39.974Z
Learning: In the kleros/curate-v2 repository, the kleros/ui-components-library overrides Tailwind's lg breakpoint to 900px (not the default 1024px). The LG_BREAKPOINT constant in web/src/styles/breakpoints.ts is set to 900 to match this override. This configuration is imported via the source directive in global.css.
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/index.tsx:15-28
Timestamp: 2025-10-24T21:25:59.174Z
Learning: In Tailwind v4, when using CSS variables from external libraries like kleros/ui-components-library, add the `source` directive in global.css to tell Tailwind to scan and generate utility classes from those variables. Example: `source "../node_modules/kleros/ui-components-library";`
🧬 Code graph analysis (3)
web/src/components/HistoryDisplay/index.tsx (4)
web/src/hooks/queries/useRequestsQuery.ts (1)
  • useItemRequests (48-64)
web/src/hooks/useToggleThemeContext.tsx (1)
  • useTheme (18-20)
web/src/components/StyledSkeleton.tsx (1)
  • HistorySkeletonCard (5-12)
web/src/utils/date.ts (1)
  • formatDate (28-32)
web/src/components/ItemCard/index.tsx (2)
web/src/utils/index.ts (1)
  • cn (44-46)
web/src/components/RegistryCard/StatusBanner.tsx (1)
  • mapFromSubgraphStatus (28-40)
web/src/pages/AllLists/RegistryDetails/List/index.tsx (1)
web/src/hooks/queries/useItemsQuery.ts (1)
  • ItemDetailsFragment (6-6)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Redirect rules - curate-v2
  • GitHub Check: Header rules - curate-v2
  • GitHub Check: Pages changed - curate-v2
🔇 Additional comments (5)
web/src/components/HistoryDisplay/index.tsx (5)

19-19: LGTM! Type alias correctly defined.

The TimelineItem type alias properly extracts the item type from the CustomTimeline component's items prop using TypeScript utility types.


23-24: LGTM! Theme detection properly implemented.

The theme hook usage and light theme detection are correct. The boolean flag appropriately drives the color selection logic throughout the component.


26-34: Previous issue addressed—dependency array now complete.

The useMemo dependency array now correctly includes isItem, ensuring items recompute when any dependency changes. This addresses the concern from the previous review.


36-46: LGTM! Rendering logic clean and correct.

The component rendering handles all states appropriately—loading, empty, and populated. The Tailwind arbitrary variant syntax on line 42 correctly targets nested .party-wrapper elements for responsive max-height control.


48-53: LGTM! Card wrapper properly structured.

The Card component is correctly used with appropriate Tailwind classes for layout and spacing. The structure cleanly wraps the header and timeline content.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (1)
web/src/components/ItemCard/index.tsx (1)

49-57: Replace deep .button-text selector with textClassName on Button

The Button is still styled using the deep selector:

className={clsx(
  "bg-transparent p-0 flex-row-reverse gap-2",
  "[&_.button-text]:text-klerosUIComponentsPrimaryBlue [&_.button-text]:font-normal",
  "focus:bg-transparent hover:bg-transparent"
)}

This couples ItemCard to the internal .button-text class of @kleros/ui-components-library and is brittle against library changes. The v3 Button exposes a textClassName prop for exactly this purpose.

Prefer:

<Button
  className={cn(
    "bg-transparent p-0 flex-row-reverse gap-2",
    "focus:bg-transparent hover:bg-transparent"
  )}
  textClassName="text-klerosUIComponentsPrimaryBlue font-normal"
  text="Open"
  Icon={ArrowIcon}
/>

This keeps the outer Button styling in className and the text-specific styling in textClassName, without relying on internal selectors.

🧹 Nitpick comments (2)
web/src/components/ItemCard/index.tsx (2)

9-10: Prefer cn consistently instead of raw clsx where possible

You already import cn, which wraps clsx and twMerge. Using both cn and clsx in the same file is a bit inconsistent and loses Tailwind class merging on the Button.

You can simplify and standardize by routing the Button classes through cn as well:

-import { cn } from "~src/utils";
-import clsx from "clsx";
+import { cn } from "~src/utils";
...
-        <Button
-          className={clsx(
+        <Button
+          className={cn(
             "bg-transparent p-0 flex-row-reverse gap-2",
             "[&_.button-text]:text-klerosUIComponentsPrimaryBlue [&_.button-text]:font-normal",
             "focus:bg-transparent hover:bg-transparent"
           )}

25-57: Consider avoiding nested interactive regions for better accessibility

Right now the Card is fully clickable via onClick, and an inner Button is rendered without its own handler:

<Card ... onClick={() => navigateAndScrollTop(`/lists/item/${id?.toString()}`)}>
  ...
  <Button ... text="Open" Icon={ArrowIcon} />
</Card>

This creates a nested interactive element pattern (a button inside a clickable container), which can be sub‑optimal for accessibility and keyboard/screen‑reader users.

Two possible improvements:

  1. Move navigation onto the Button and make the Card non-interactive; or
  2. Keep the Card clickable but render the right-hand control as non-interactive text/icon (or ensure the inner Button is aria-hidden / non-focusable).

Not urgent, but worth aligning with your broader accessibility goals during this Tailwind/UI‑library migration.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cea5d0c and 4157613.

📒 Files selected for processing (1)
  • web/src/components/ItemCard/index.tsx (2 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/styles/breakpoints.ts:1-1
Timestamp: 2025-11-14T22:12:39.974Z
Learning: In the kleros/curate-v2 repository, the kleros/ui-components-library overrides Tailwind's lg breakpoint to 900px (not the default 1024px). The LG_BREAKPOINT constant in web/src/styles/breakpoints.ts is set to 900 to match this override. This configuration is imported via the source directive in global.css.
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/index.tsx:15-28
Timestamp: 2025-10-24T21:25:59.174Z
Learning: In Tailwind v4, when using CSS variables from external libraries like kleros/ui-components-library, add the `source` directive in global.css to tell Tailwind to scan and generate utility classes from those variables. Example: `source "../node_modules/kleros/ui-components-library";`
🧬 Code graph analysis (1)
web/src/components/ItemCard/index.tsx (2)
web/src/utils/index.ts (1)
  • cn (44-46)
web/src/components/RegistryCard/StatusBanner.tsx (1)
  • mapFromSubgraphStatus (28-40)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Redirect rules - curate-v2
  • GitHub Check: Header rules - curate-v2
  • GitHub Check: Pages changed - curate-v2
🔇 Additional comments (3)
web/src/components/ItemCard/index.tsx (3)

12-15: Responsive calc helpers look correct and match LG breakpoint configuration

The landscapeGridColsCalc and landscapeGapCalc expressions are well-formed calc() formulas and use 900px as the lower clamp, which matches the overridden lg breakpoint (900px) configured for this app. This should give smooth interpolation between 900px and 1250px.

Based on learnings


25-37: Card layout and grid template look valid; grid-rows syntax issue resolved

The Card container and grid wrapper now:

  • Use flex grow w-full h-max lg:h-16 on the Card, aligning with a fixed-height row on large screens.
  • Define grid-rows-[repeat(3,min-content)] on mobile and lg:grid-rows-[1fr] on large screens, fixing the earlier invalid repeat(3,) syntax.
  • Apply columnGap via responsiveSize(12, 32, 900), which aligns with the 900px LG breakpoint configuration.

No functional issues here; the previous repeat(3,) bug is fully addressed.


39-47: Identifier fields mapping and responsive gap look good

The left-hand content column:

  • Uses a clear mobile (flex-col) vs. desktop (lg:flex-row) layout and interpolated lg:gap-[calc(...)] spacing, consistent with the calc helpers above.
  • Adds a key={prop.label} to ItemField, resolving the earlier missing-key issue for the mapped children.

Assuming label is unique per item or per identifier prop, this is sufficient; otherwise you can fall back to a composite key (e.g. ${prop.type}-${prop.label}) later if needed.

coderabbitai[bot]
coderabbitai bot previously approved these changes Nov 18, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

♻️ Duplicate comments (2)
web/src/components/ActionButton/index.tsx (1)

49-56: Re: Button isDisabled prop — past concern still unresolved.

The change from disabled to isDisabled was flagged in a previous review, with a web search suggesting that v3 uses disabled, not isDisabled. However, I was unable to find definitive documentation confirming the correct prop name for @kleros/ui-components-library v3.6.0.

Some UI libraries like Chakra UI use isDisabled, while others use standard HTML disabled. If the Kleros library is built on React Aria Components, isDisabled would be correct. Otherwise, this may cause the button to not be disabled as expected.

Please verify which prop the Button component from @kleros/ui-components-library v3.6.0 actually accepts. If it's disabled, revert both occurrences (lines 50 and 65). If it's isDisabled, the implementation is correct.

Run this script to check the Button component's TypeScript definition:

#!/bin/bash
# Check Button component props in node_modules
if [ -f "node_modules/@kleros/ui-components-library/dist/index.d.ts" ]; then
  echo "=== Checking Button interface in type definitions ==="
  rg -A 20 "interface.*Button.*Props|type.*Button.*Props" node_modules/@kleros/ui-components-library/dist/
else
  echo "Type definition file not found"
fi

# Also check for Button export
echo ""
echo "=== Button exports ==="
rg "export.*Button" node_modules/@kleros/ui-components-library/dist/
web/src/global.css (1)

1-5: Critical: Reorder @import "tailwindcss" before other at-rules.

Currently @import "tailwindcss"; on Line 4 comes after @tailwind and @source, which violates the CSS rule that all @import directives must appear before other at-rules (Biome is flagging this). This can lead to parse issues and broken Tailwind processing.

Reorder the header like this so both imports come first:

-@import "../../node_modules/@kleros/ui-components-library/dist/assets/theme.css";
-@tailwind utilities;
-@source "../../node_modules/@kleros/ui-components-library";
-@import "tailwindcss";
-@custom-variant dark (&:where(.dark, .dark *));
+@import "../../node_modules/@kleros/ui-components-library/dist/assets/theme.css";
+@import "tailwindcss";
+@source "../../node_modules/@kleros/ui-components-library";
+@tailwind utilities;
+@custom-variant dark (&:where(.dark, .dark *));
🧹 Nitpick comments (6)
web/src/components/HistoryDisplay/Header.tsx (1)

6-11: Header Tailwind conversion looks good; consider marking the icon decorative

Layout and Tailwind classes are straightforward and match the intended header structure. For accessibility, you might want to mark the HistoryIcon as decorative so screen readers rely on the visible “History” text:

-        <HistoryIcon width={17} height={16} className="fill-klerosUIComponentsPrimaryText" />
+        <HistoryIcon
+          width={17}
+          height={16}
+          className="fill-klerosUIComponentsPrimaryText"
+          aria-hidden="true"
+        />
web/src/components/HistoryDisplay/index.tsx (2)

36-41: Prefer semantic element for empty state and consider simplifying Component memo

Two small points here:

  1. label is meant for form controls; for “No requests yet.” a p or span would be more semantic and avoids suggesting a control association:
-    else if (items.length === 0) return <label className="self-center pb-8">No requests yet.</label>;
+    else if (items.length === 0) return <p className="self-center pb-8">No requests yet.</p>;
  1. The Component useMemo is fine as-is, but it could be inlined into JSX to reduce indirection if you want to simplify later.

58-117: Color constants repeated across cases – optional centralization

The same hex colors (#009aff, #6cc5ff, #9013fe, #b45fff, #f60c36, #ff5a78, #00c42b, #65dc7f) are repeated across multiple item variants. This is fine functionally, but if these map to named theme tokens, it may be worth extracting a small helper (e.g., getVariantColor(isLightTheme, "primary" | "warning" | ...)) or constants to keep things DRY and make future palette changes safer.

web/src/components/InformationCards/RegistryInformationCard/Policies.tsx (1)

25-32: Consider using Tailwind utilities for all spacing.

The component mixes inline styles (paddingInline, gap via style prop) with Tailwind classes. While responsiveSize() provides dynamic sizing, this creates an inconsistent styling approach within a Tailwind migration.

If responsiveSize() returns static breakpoint-based values, consider replacing inline styles with Tailwind responsive utilities:

-    <div
-      className="flex flex-col justify-center w-full py-6 mt-4 bg-klerosUIComponentsMediumBlue leading-6 lg:flex-row lg:justify-between"
-      style={{ paddingInline: responsiveSize(24, 32) }}
-    >
+    <div className="flex flex-col justify-center w-full px-6 py-6 mt-4 bg-klerosUIComponentsMediumBlue leading-6 lg:flex-row lg:justify-between lg:px-8">

Similarly for line 32:

-      <div className="flex flex-wrap" style={{ gap: responsiveSize(16, 24) }}>
+      <div className="flex flex-wrap gap-4 lg:gap-6">

If responsiveSize() provides non-standard breakpoint values that don't map to Tailwind's spacing scale, the current approach is acceptable.

web/src/components/InformationCards/RegistryInformationCard/index.tsx (1)

69-73: Consider Tailwind utilities for consistent spacing.

Similar to the Policies component, this mixes inline styles (marginBlock, marginInline) with Tailwind classes. While responsiveSize() provides dynamic values, consider whether standard Tailwind responsive utilities could replace these:

-      <hr
-        className="border-none h-px bg-klerosUIComponentsStroke"
-        style={{ marginBlock: responsiveSize(20, 28), marginInline: responsiveSize(24, 32) }}
-      />
+      <hr className="border-none h-px bg-klerosUIComponentsStroke my-5 mx-6 lg:my-7 lg:mx-8" />

And for line 73:

-      <div className="flex flex-wrap justify-between gap-5 pb-3" style={{ paddingInline: responsiveSize(24, 32) }}>
+      <div className="flex flex-wrap justify-between gap-5 pb-3 px-6 lg:px-8">

If responsiveSize() returns values that don't align with Tailwind's spacing scale, the inline style approach is reasonable.

web/src/components/StatsAndFilters/Filters.tsx (1)

47-63: Optional cleanup: remove redundant isDesktop guard and DRY icon classes.

Inside the list view toggle, the if (isDesktop) check in the ListIcon onClick is redundant because this entire block only renders when isDesktop && isListFilter is true, and the icon class strings are duplicated.

You could simplify and de-duplicate like this:

-      {isListView ? (
-        <GridIcon
-          className="w-4 h-4 overflow-hidden cursor-pointer fill-klerosUIComponentsPrimaryBlue hover:fill-klerosUIComponentsSecondaryBlue transition duration-100"
-          onClick={() => setIsListView(false)}
-        />
-      ) : (
-        <ListIcon
-          className="w-4 h-4 overflow-hidden cursor-pointer fill-klerosUIComponentsPrimaryBlue hover:fill-klerosUIComponentsSecondaryBlue transition duration-100"
-          onClick={() => {
-            if (isDesktop) {
-              setIsListView(true);
-            }
-          }}
-        />
-      )}
+      {isListView ? (
+        <GridIcon
+          className="w-4 h-4 overflow-hidden cursor-pointer fill-klerosUIComponentsPrimaryBlue hover:fill-klerosUIComponentsSecondaryBlue transition duration-100"
+          onClick={() => setIsListView(false)}
+        />
+      ) : (
+        <ListIcon
+          className="w-4 h-4 overflow-hidden cursor-pointer fill-klerosUIComponentsPrimaryBlue hover:fill-klerosUIComponentsSecondaryBlue transition duration-100"
+          onClick={() => setIsListView(true)}
+        />
+      )}

(Optionally, pull the shared class string into a small const iconClassName = "..." to avoid repeating it.)

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4157613 and ea5feab.

📒 Files selected for processing (12)
  • web/src/components/ActionButton/index.tsx (2 hunks)
  • web/src/components/HistoryDisplay/Header.tsx (1 hunks)
  • web/src/components/HistoryDisplay/Party/index.tsx (1 hunks)
  • web/src/components/HistoryDisplay/index.tsx (7 hunks)
  • web/src/components/InformationCards/RegistryInformationCard/Policies.tsx (2 hunks)
  • web/src/components/InformationCards/RegistryInformationCard/TopInfo.tsx (2 hunks)
  • web/src/components/InformationCards/RegistryInformationCard/index.tsx (4 hunks)
  • web/src/components/InformationCards/StatusDisplay.tsx (2 hunks)
  • web/src/components/StatsAndFilters/Filters.tsx (1 hunks)
  • web/src/global.css (1 hunks)
  • web/src/layout/Header/navbar/Menu/Help.tsx (2 hunks)
  • web/src/pages/AllLists/RegistryDetails/ItemsDownloadLabel.tsx (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • web/src/pages/AllLists/RegistryDetails/ItemsDownloadLabel.tsx
  • web/src/components/InformationCards/StatusDisplay.tsx
  • web/src/components/InformationCards/RegistryInformationCard/TopInfo.tsx
  • web/src/components/HistoryDisplay/Party/index.tsx
🧰 Additional context used
🧠 Learnings (6)
📓 Common learnings
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/styles/breakpoints.ts:1-1
Timestamp: 2025-11-14T22:12:39.974Z
Learning: In the kleros/curate-v2 repository, the kleros/ui-components-library overrides Tailwind's lg breakpoint to 900px (not the default 1024px). The LG_BREAKPOINT constant in web/src/styles/breakpoints.ts is set to 900 to match this override. This configuration is imported via the source directive in global.css.
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/index.tsx:15-28
Timestamp: 2025-10-24T21:25:59.174Z
Learning: In Tailwind v4, when using CSS variables from external libraries like kleros/ui-components-library, add the `source` directive in global.css to tell Tailwind to scan and generate utility classes from those variables. Example: `source "../node_modules/kleros/ui-components-library";`
📚 Learning: 2025-11-14T22:12:39.974Z
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/styles/breakpoints.ts:1-1
Timestamp: 2025-11-14T22:12:39.974Z
Learning: In the kleros/curate-v2 repository, the kleros/ui-components-library overrides Tailwind's lg breakpoint to 900px (not the default 1024px). The LG_BREAKPOINT constant in web/src/styles/breakpoints.ts is set to 900 to match this override. This configuration is imported via the source directive in global.css.

Applied to files:

  • web/src/layout/Header/navbar/Menu/Help.tsx
  • web/src/global.css
📚 Learning: 2025-10-24T21:25:59.174Z
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/index.tsx:15-28
Timestamp: 2025-10-24T21:25:59.174Z
Learning: In Tailwind v4, when using CSS variables from external libraries like kleros/ui-components-library, add the `source` directive in global.css to tell Tailwind to scan and generate utility classes from those variables. Example: `source "../node_modules/kleros/ui-components-library";`

Applied to files:

  • web/src/global.css
📚 Learning: 2025-11-06T23:06:51.514Z
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/global.css:3-3
Timestamp: 2025-11-06T23:06:51.514Z
Learning: In Tailwind v4, you can use `import "tailwindcss" source("path")` syntax to control automatic content detection by passing the source() argument directly on the import statement. This is in addition to the standalone `source "path"` directive. Both syntaxes are valid: `import "tailwindcss" source("../../node_modules/kleros/ui-components-library");` and `source "../../node_modules/kleros/ui-components-library";`

Applied to files:

  • web/src/global.css
📚 Learning: 2025-10-31T19:54:12.499Z
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/Header/DesktopHeader.tsx:43-44
Timestamp: 2025-10-31T19:54:12.499Z
Learning: In Tailwind CSS v4, the important modifier uses a trailing `!` after the utility class (e.g., `fill-white!`), unlike v3 which used a leading `!` prefix (e.g., `!fill-white`). This applies to all utilities including arbitrary values and after variants (e.g., `sm:hover:bg-green-500!`).

Applied to files:

  • web/src/global.css
📚 Learning: 2025-10-31T20:37:01.310Z
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/components/OverlayPortal.tsx:5-8
Timestamp: 2025-10-31T20:37:01.310Z
Learning: In Tailwind CSS v4, the `z-<number>` syntax directly sets `z-index: <number>;` for any numeric value (e.g., `z-9999` results in `z-index: 9999;`). Arbitrary value brackets `z-[<value>]` are not required for numeric z-index values in v4.
```
<!-- [remove_learning]
dcbe3a95-44f6-47d5-806e-64b74d549e4b

Applied to files:

  • web/src/global.css
🧬 Code graph analysis (3)
web/src/components/InformationCards/RegistryInformationCard/index.tsx (2)
web/src/utils/index.ts (1)
  • cn (44-46)
web/src/components/InformationCards/RegistryInformationCard/Policies.tsx (1)
  • Policies (21-59)
web/src/components/InformationCards/RegistryInformationCard/Policies.tsx (1)
web/src/utils/getIpfsUrl.ts (1)
  • getIpfsUrl (4-8)
web/src/components/HistoryDisplay/index.tsx (4)
web/src/hooks/queries/useRequestsQuery.ts (1)
  • useItemRequests (48-64)
web/src/hooks/useToggleThemeContext.tsx (1)
  • useTheme (18-20)
web/src/components/StyledSkeleton.tsx (1)
  • HistorySkeletonCard (5-12)
web/src/utils/date.ts (1)
  • formatDate (28-32)
🪛 Biome (2.1.2)
web/src/global.css

[error] 4-4: This @import is in the wrong position.

Any @import rules must precede all other valid at-rules and style rules in a stylesheet (ignoring @charset and @layer), or else the @import rule is invalid.
Consider moving import position.

(lint/correctness/noInvalidPositionAtImportRule)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Redirect rules - curate-v2
  • GitHub Check: Header rules - curate-v2
  • GitHub Check: Pages changed - curate-v2
🔇 Additional comments (8)
web/src/layout/Header/navbar/Menu/Help.tsx (1)

49-57: Fix invalid z-index utility.

Line 52 uses z-1, which is not a valid Tailwind utility. Tailwind's default z-index scale includes 0, 10, 20, 30, 40, 50, and auto, but not 1.

Apply this diff to use arbitrary value syntax:

-          "flex flex-col absolute max-h-[80vh] overflow-y-auto w-[86vw] max-w-[444px] top-[5%] left-1/2 transform -translate-x-1/2 z-1 p-3 pb-6",
+          "flex flex-col absolute max-h-[80vh] overflow-y-auto w-[86vw] max-w-[444px] top-[5%] left-1/2 transform -translate-x-1/2 z-[1] p-3 pb-6",
⛔ Skipped due to learnings
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/components/OverlayPortal.tsx:5-8
Timestamp: 2025-10-31T20:37:01.310Z
Learning: In Tailwind CSS v4, the `z-<number>` syntax directly sets `z-index: <number>;` for any numeric value (e.g., `z-9999` results in `z-index: 9999;`). Arbitrary value brackets `z-[<value>]` are not required for numeric z-index values in v4.
```
<!-- [remove_learning]
dcbe3a95-44f6-47d5-806e-64b74d549e4b
web/src/components/HistoryDisplay/index.tsx (3)

1-20: Type aliasing TimelineItem off CustomTimeline props is a solid choice

Deriving TimelineItem from React.ComponentProps<typeof CustomTimeline>["items"][number] keeps this file aligned with the library’s item shape and avoids drift when the component API changes. Imports for Card, CustomTimeline, clsx, and useTheme also look consistent with the Tailwind-and-theme migration goals.


21-35: items useMemo wiring and dependencies look correct

items is recomputed only when data, isLightTheme, or isItem change, which matches the arguments passed into constructItemsFromRequest. The guard if (!items || isLoading) later safely handles the undefined case from data?.requests. This addresses the earlier dependency issue around isItem.


43-48: Card wrapper Tailwind layout matches intent

Wrapping the history content in a Card with flex flex-col w-full h-auto items-start gap-14 py-6 px-8 gives a clear, responsive container and aligns with the Tailwind-based layout approach elsewhere. No issues spotted here.

web/src/components/InformationCards/RegistryInformationCard/index.tsx (2)

51-51: Good use of the cn utility for class composition.

The cn utility properly merges the base classes with the optional className prop, enabling external styling customization while maintaining type safety.


76-79: Arbitrary Tailwind variants in tooltipProps are supported.

The Copiable component in @kleros/ui-components-library v3 passes tooltipProps.className through to the tooltip, supporting arbitrary Tailwind utility classes and variants. The code at lines 76–79 using [&_small]:text-sm is correct.

One consideration: ensure your Tailwind build includes the library package as a source so these arbitrary classes are picked up during the build process.

web/src/components/InformationCards/RegistryInformationCard/Policies.tsx (1)

13-14: Based on my verification, I can now provide the rewritten review comment:

The hover state syntax is valid and the custom color is properly available.

The hover:[&_svg]:fill-klerosUIComponentsSecondaryBlue syntax is correctly using Tailwind v4's arbitrary variants with descendant selectors. The custom color klerosUIComponentsSecondaryBlue is sourced from the kleros/ui-components-library via the @source directive in global.css, which scans and makes external CSS variables available to Tailwind. This same color is already successfully used in Filters.tsx with identical syntax, confirming it works as intended.

web/src/components/StatsAndFilters/Filters.tsx (1)

34-45: Filters.tsx DropdownSelect v3 usage confirmed correct; flag separate migration issue in ChainInput.tsx.

The v3 API pattern you're verifying is confirmed across the codebase:

  • Search.tsx uses identical { id, itemValue, text } item shape + callback((item) => item.itemValue)
  • Filters.tsx correctly mirrors this pattern with defaultSelectedKey={order} pointing to item id

Critical finding: ChainInput.tsx (web/src/pages/SubmitItem/ItemField/FieldInput/ChainInput.tsx) is using an incompatible older API—{ text, value } items with callback receiving raw values instead of item objects. This file likely has a runtime bug or needs immediate migration to the v3 pattern to match the rest of the codebase.

For Filters.tsx specifically: the implementation is correct and consistent with the library's v3.6.0 API as deployed elsewhere.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
web/src/components/HistoryDisplay/index.tsx (1)

98-105: Use challengeTime for “Removal Challenged” subtitle for consistency

In the registration branch, the “Challenged” event subtitle uses request.challengeTime, but in the clearing branch it uses request.submissionTime, which likely shows the wrong timestamp for the challenge event.

Consider aligning it with the registration case:

-        subtitle: formatDate(request.submissionTime),
+        subtitle: formatDate(request.challengeTime),

This keeps the “Removal Challenged” entry anchored to when the challenge actually occurred.

♻️ Duplicate comments (1)
web/src/layout/Header/navbar/Menu/Help.tsx (1)

70-70: Fix invalid Tailwind line-height utility.

Line 70 uses leading-18px, which is invalid Tailwind syntax. Arbitrary line-height values must use square brackets: leading-[18px].

This issue was previously flagged and marked as addressed, but the invalid syntax is still present in the current code.

Apply this diff:

-            <small className="text-base leading-18px font-normal transition-colors duration-100 group-hover:text-klerosUIComponentsSecondaryPurple">
+            <small className="text-base leading-[18px] font-normal transition-colors duration-100 group-hover:text-klerosUIComponentsSecondaryPurple">
               {item.text}
             </small>
🧹 Nitpick comments (2)
web/src/components/InformationCards/RegistryInformationCard/TopInfo.tsx (1)

14-14: Responsive gap calculation matches LG breakpoint; consider documenting intent

The landscapeColumnGapCalc class correctly interpolates horizontal gap from 24px → 32px between 900px and 1250px viewport widths, aligning with the overridden lg breakpoint at 900px. A short comment explaining this formula would help future maintainability.

Based on learnings

web/src/components/HistoryDisplay/index.tsx (1)

26-41: Simplify CustomTimeline className; clsx is unnecessary here

className is a static string with no conditional pieces, so clsx doesn’t add value and the extra import can be dropped.

-import clsx from "clsx";
@@
-    return <CustomTimeline className={clsx("w-full mb-8", "[&_h2]:m-0 [&_div]:max-h-none")} {...{ items }} />;
+    return (
+      <CustomTimeline
+        className="w-full mb-8 [&_h2]:m-0 [&_div]:max-h-none"
+        {...{ items }}
+      />
+    );

The items computation and loading/empty states otherwise look fine.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ea5feab and 390ab82.

📒 Files selected for processing (4)
  • web/src/components/HistoryDisplay/index.tsx (7 hunks)
  • web/src/components/InformationCards/RegistryInformationCard/TopInfo.tsx (2 hunks)
  • web/src/components/InformationCards/RegistryInformationCard/index.tsx (4 hunks)
  • web/src/layout/Header/navbar/Menu/Help.tsx (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • web/src/components/InformationCards/RegistryInformationCard/index.tsx
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/styles/breakpoints.ts:1-1
Timestamp: 2025-11-14T22:12:39.974Z
Learning: In the kleros/curate-v2 repository, the kleros/ui-components-library overrides Tailwind's lg breakpoint to 900px (not the default 1024px). The LG_BREAKPOINT constant in web/src/styles/breakpoints.ts is set to 900 to match this override. This configuration is imported via the source directive in global.css.
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/index.tsx:15-28
Timestamp: 2025-10-24T21:25:59.174Z
Learning: In Tailwind v4, when using CSS variables from external libraries like kleros/ui-components-library, add the `source` directive in global.css to tell Tailwind to scan and generate utility classes from those variables. Example: `source "../node_modules/kleros/ui-components-library";`
📚 Learning: 2025-11-14T22:12:39.974Z
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/styles/breakpoints.ts:1-1
Timestamp: 2025-11-14T22:12:39.974Z
Learning: In the kleros/curate-v2 repository, the kleros/ui-components-library overrides Tailwind's lg breakpoint to 900px (not the default 1024px). The LG_BREAKPOINT constant in web/src/styles/breakpoints.ts is set to 900 to match this override. This configuration is imported via the source directive in global.css.

Applied to files:

  • web/src/layout/Header/navbar/Menu/Help.tsx
🧬 Code graph analysis (2)
web/src/components/HistoryDisplay/index.tsx (4)
web/src/hooks/queries/useRequestsQuery.ts (1)
  • useItemRequests (48-64)
web/src/hooks/useToggleThemeContext.tsx (1)
  • useTheme (18-20)
web/src/components/StyledSkeleton.tsx (1)
  • HistorySkeletonCard (5-12)
web/src/utils/date.ts (1)
  • formatDate (28-32)
web/src/components/InformationCards/RegistryInformationCard/TopInfo.tsx (4)
web/src/utils/index.ts (2)
  • isUndefined (5-5)
  • cn (44-46)
web/src/utils/getIpfsUrl.ts (1)
  • getIpfsUrl (4-8)
web/src/consts/index.ts (1)
  • DEFAULT_LIST_LOGO (23-23)
web/src/consts/chains.ts (1)
  • SUPPORTED_CHAINS (9-11)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: CodeQL
  • GitHub Check: Redirect rules - curate-v2
  • GitHub Check: Header rules - curate-v2
  • GitHub Check: Pages changed - curate-v2
🔇 Additional comments (7)
web/src/layout/Header/navbar/Menu/Help.tsx (1)

52-54: Fix undefined z-index utility z-1.

Line 52 uses z-1, which is not a valid Tailwind utility. Tailwind v4 provides z-0, z-10, z-20, z-30, z-40, and z-50 by default. Replace z-1 with an appropriate z-index value (likely z-10).

The shadow-custom utility is correctly defined via the --shadow-custom CSS variable in global.css and will work as expected in Tailwind v4.

⛔ Skipped due to learnings
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/components/OverlayPortal.tsx:5-8
Timestamp: 2025-10-31T20:37:01.310Z
Learning: In Tailwind CSS v4, the `z-<number>` syntax directly sets `z-index: <number>;` for any numeric value (e.g., `z-9999` results in `z-index: 9999;`). Arbitrary value brackets `z-[<value>]` are not required for numeric z-index values in v4.
```
<!-- [remove_learning]
dcbe3a95-44f6-47d5-806e-64b74d549e4b
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/Header/DesktopHeader.tsx:43-44
Timestamp: 2025-10-31T19:54:12.499Z
Learning: In Tailwind CSS v4, the important modifier uses a trailing `!` after the utility class (e.g., `fill-white!`), unlike v3 which used a leading `!` prefix (e.g., `!fill-white`). This applies to all utilities including arbitrary values and after variants (e.g., `sm:hover:bg-green-500!`).
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/styles/breakpoints.ts:1-1
Timestamp: 2025-11-14T22:12:39.974Z
Learning: In the kleros/curate-v2 repository, the kleros/ui-components-library overrides Tailwind's lg breakpoint to 900px (not the default 1024px). The LG_BREAKPOINT constant in web/src/styles/breakpoints.ts is set to 900 to match this override. This configuration is imported via the source directive in global.css.
web/src/components/InformationCards/RegistryInformationCard/TopInfo.tsx (3)

8-11: Utility imports are appropriate and fully used

cn and isUndefined are both used below (layout classes and skeleton conditions), so the shared utils import is correct with no dead code.


36-63: Top-level layout and logo/title/description skeletons look correct

The flex layout, responsive padding via responsiveSize, isUndefined-based skeleton rendering for logoURI, title, and description, plus the IPFS logo fallback on image error all look consistent and robust for loading states and broken logos.


64-94: Right column layout, cn usage, and Copiable/link styling are solid

The cn-composed flex container with responsive gap/shrink behavior, Copiable configuration (including tooltipProps), and the styled anchor (primary blue, hover underline, external link attributes) preserve expected behavior while matching the Tailwind migration.

web/src/components/HistoryDisplay/index.tsx (3)

1-24: Type-safe wiring between theme, CustomTimeline, and item shape looks solid

Imports of Card/CustomTimeline, useTheme, and the TimelineItem alias derived from CustomTimeline’s items prop, plus the isLightTheme boolean, all line up correctly with later usage; no issues spotted here.


44-48: Card wrapper Tailwind layout looks appropriate

Using a flex column Card with full width, auto height, padding, and gap is a reasonable migration from styled-components here; structure and composition with Header and the timeline content read cleanly.


51-57: constructItemsFromRequest typing and visual semantics are consistent

Updating constructItemsFromRequest to return TimelineItem[] with a locally typed historyItems array now matches the reducer usage (acc.push(...history)). The color variants and icons for registration vs. clearing (included vs. rejected/removed) are coherent and align with the intended positive/negative states.

Also applies to: 61-62, 69-71, 77-88, 90-97, 101-102, 108-116, 120-121

coderabbitai[bot]
coderabbitai bot previously approved these changes Nov 19, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 9

♻️ Duplicate comments (1)
web/src/pages/SubmitItem/ItemField/FieldInput/ImageInput.tsx (1)

9-10: Duplicate: See FileInput.tsx comment.

The typo and code duplication issues here are identical to those in FileInput.tsx lines 9-10. Refer to that comment for the suggested fix.

🧹 Nitpick comments (10)
web/src/pages/SubmitItem/ItemField/FieldInput/ChainInput.tsx (1)

8-20: DropdownSelect migration looks correct; consider small cleanup and verify defaultValue semantics

The new items shape ({ id, text, itemValue }) and callback={(item) => handleChange(item.itemValue)} look consistent with the updated DropdownSelect API and correctly keep handleWrite receiving the chainId as a string.

As a minor tidy-up, handleChange is now only ever called with a number, so you could either narrow its signature to number or inline it in the callback to reduce indirection, for example:

-  const handleChange = (value: string | number) => {
-    handleWrite(value.toString());
-  };
   return (
     <DropdownSelect
       items={[
         { id: mainnet.id, text: getChainName(mainnet.id), itemValue: mainnet.id },
         { id: arbitrum.id, text: getChainName(arbitrum.id), itemValue: arbitrum.id },
         { id: gnosis.id, text: getChainName(gnosis.id), itemValue: gnosis.id },
         { id: polygon.id, text: getChainName(polygon.id), itemValue: polygon.id },
       ]}
-      callback={(item) => handleChange(item.itemValue)}
+      callback={(item) => handleWrite(item.itemValue.toString())}
       defaultValue={Number(fieldProp.value ?? mainnet.id)}
     />
   );

Also, since the DropdownSelect items API changed, please double-check the v3 docs to confirm that defaultValue should still be the numeric value you’re passing (Number(fieldProp.value ?? mainnet.id)) and not, for example, the id field; otherwise the initial selected chain might not match expectations.

web/src/pages/SubmitItem/Policy/ReadPolicy.tsx (1)

10-14: Tailwind migration is fine; consider hardening the URL construction.

The switch from a styled-component to a Link with Tailwind classes looks correct and keeps behavior intact. To make the query parameter handling more robust (and future‑proof if policyURI ever contains & or other reserved characters), consider encoding the URL value:

-  return (
-    <Link className="self-center text-xl mb-8" to={`/attachment/?url=${getIpfsUrl(policyURI ?? "")}`}>
+  return (
+    <Link
+      className="self-center text-xl mb-8"
+      to={`/attachment/?url=${encodeURIComponent(getIpfsUrl(policyURI ?? ""))}`}
+    >
       → Read the policy here ←
     </Link>
   );

Optionally, you could also skip rendering the link when there is no policyURI available (e.g., early return null), to avoid navigating to /attachment/?url= with an empty value.

web/src/pages/SubmitItem/ItemField/FieldInput/NumberInput.tsx (1)

16-16: Consider refactoring inline style to Tailwind utilities.

Using an inline style attribute with responsiveSize() undermines the Tailwind migration. Consider refactoring this to use Tailwind's responsive spacing utilities or CSS custom properties defined in @theme.

For example, if responsiveSize(68, 40) represents responsive margin-bottom values, you could use Tailwind classes:

-      style={{ marginBottom: responsiveSize(68, 40) }}
+      className={cn("w-[80vw] mb-10 lg:mb-17", landscapeWitdhCalc)}
-      className={cn("w-[80vw]", landscapeWitdhCalc)}

Or define a CSS variable in @theme and use it:

@theme {
  --spacing-responsive-bottom: 40px;
  @media (min-width: 900px) {
    --spacing-responsive-bottom: 68px;
  }
}
-      style={{ marginBottom: responsiveSize(68, 40) }}
+      className={cn("w-[80vw] mb-(--spacing-responsive-bottom)", landscapeWitdhCalc)}
-      className={cn("w-[80vw]", landscapeWitdhCalc)}
web/src/pages/SubmitItem/Header/index.tsx (1)

46-46: Consider completing the Tailwind migration.

The code mixes Tailwind classes with inline styles using responsiveSize. While acceptable during migration, consider replacing the inline styles with Tailwind's responsive utilities for consistency.

For example, paddingInline: responsiveSize(24, 32) could be replaced with:

-        style={{ marginBottom: responsiveSize(36, 36), paddingInline: responsiveSize(24, 32) }}
+        className={clsx("flex flex-wrap justify-between gap-6", "h-auto w-[80vw] lg:w-[91vw]", "mt-[60px] py-6 mb-9 px-6 lg:px-8")}
web/src/pages/SubmitItem/ItemField/FieldInput/TextInput.tsx (1)

7-7: Extract duplicated constant to a shared utility.

The landscapeWitdhCalc (or corrected: landscapeWidthCalc) constant is duplicated across TextInput.tsx (line 7), AddressInput.tsx (line 8), and LinkInput.tsx (line 7). This violates the DRY principle.

Consider extracting this to a shared constants file, for example web/src/styles/constants.ts:

export const LANDSCAPE_WIDTH_CALC = "lg:w-[calc(200px+(720-200)*(min(max(100vw,375px),1250px)-375px)/(1250-375))]";

Then import and use it in all three files:

import { LANDSCAPE_WIDTH_CALC } from "~src/styles/constants";

// Usage:
className={cn("w-[80vw]", LANDSCAPE_WIDTH_CALC)}
web/src/pages/SubmitItem/Preview/index.tsx (1)

10-10: Consider removing redundant py-0 utility.

The py-0 class is redundant when no vertical padding is needed (which is the default). You can safely remove it for cleaner code.

-    <div className="flex flex-col items-center w-full py-0" style={{ paddingInline: responsiveSize(10, 130) }}>
+    <div className="flex flex-col items-center w-full" style={{ paddingInline: responsiveSize(10, 130) }}>
web/src/pages/SubmitItem/ItemField/FieldInput/LongTextInput.tsx (1)

7-7: Consider extracting the responsive width calculation to a shared utility.

The landscapeWitdhCalc (once the typo is fixed) contains a complex responsive width calculation that appears to be duplicated across multiple FieldInput components per the AI summary. Consider extracting this to a shared constant or utility function to improve maintainability and ensure consistency.

For example, in web/src/styles/responsiveSize.ts or a new web/src/styles/responsiveWidth.ts:

export const LANDSCAPE_WIDTH_CALC = "lg:w-[calc(200px+(720-200)*(min(max(100vw,375px),1250px)-375px)/(1250-375))]";

Then import and use across all FieldInput components:

+import { LANDSCAPE_WIDTH_CALC } from "styles/responsiveWidth";
-const landscapeWitdhCalc = "lg:w-[calc(200px+(720-200)*(min(max(100vw,375px),1250px)-375px)/(1250-375))]";
web/src/pages/SubmitItem/index.tsx (2)

14-14: Consider using cn utility instead of clsx for consistency.

Other migrated files use the cn utility (which combines clsx and tailwind-merge) for className composition. Using cn here would ensure Tailwind class conflicts are properly resolved and maintain consistency with the rest of the codebase.

-import clsx from "clsx";
+import { cn } from "~src/utils";
       <div
-        className={clsx("flex flex-col w-full max-w-landscape", "bg-klerosUIComponentsLightBackground my-0 mx-auto")}
+        className={cn("flex flex-col w-full max-w-landscape", "bg-klerosUIComponentsLightBackground my-0 mx-auto")}
         style={{
           paddingInline: responsiveSize(24, 32),
           paddingTop: responsiveSize(24, 28),
           paddingBottom: responsiveSize(76, 96),
         }}
       >

Also applies to: 38-45


59-63: LGTM with minor suggestion.

The not-connected state UI is clear and functional. The migration to Tailwind classes is correctly applied.

For improved semantics, consider wrapping the content in a more semantic element:

-          <div className="flex flex-col items-center text-center text-klerosUIComponentsPrimaryText">
+          <section className="flex flex-col items-center text-center text-klerosUIComponentsPrimaryText" aria-labelledby="connect-prompt">
+            <h2 id="connect-prompt" className="sr-only">Connect Wallet Required</h2>
             To submit a new item, connect first
             <hr />
             <ConnectWallet />
-          </div>
+          </section>
web/src/pages/SubmitItem/Policy/ConfirmationBox.tsx (1)

5-7: Consider removing the empty interface.

The IConfirmationBox interface is empty and the component takes no props. You can simplify by removing the interface and type annotation entirely.

Apply this diff to simplify:

-interface IConfirmationBox {}
-
-const ConfirmationBox: React.FC<IConfirmationBox> = ({}) => {
+const ConfirmationBox: React.FC = () => {
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 390ab82 and 299dcfa.

📒 Files selected for processing (26)
  • web/src/pages/SubmitItem/Header/index.tsx (2 hunks)
  • web/src/pages/SubmitItem/ItemField/FieldInput/AddressInput.tsx (1 hunks)
  • web/src/pages/SubmitItem/ItemField/FieldInput/BooleanInput.tsx (1 hunks)
  • web/src/pages/SubmitItem/ItemField/FieldInput/ChainInput.tsx (1 hunks)
  • web/src/pages/SubmitItem/ItemField/FieldInput/FileInput.tsx (2 hunks)
  • web/src/pages/SubmitItem/ItemField/FieldInput/ImageInput.tsx (2 hunks)
  • web/src/pages/SubmitItem/ItemField/FieldInput/LinkInput.tsx (1 hunks)
  • web/src/pages/SubmitItem/ItemField/FieldInput/LongTextInput.tsx (1 hunks)
  • web/src/pages/SubmitItem/ItemField/FieldInput/NumberInput.tsx (1 hunks)
  • web/src/pages/SubmitItem/ItemField/FieldInput/StyledField.tsx (0 hunks)
  • web/src/pages/SubmitItem/ItemField/FieldInput/TextInput.tsx (1 hunks)
  • web/src/pages/SubmitItem/ItemField/index.tsx (1 hunks)
  • web/src/pages/SubmitItem/NavigationButtons/NextButton.tsx (1 hunks)
  • web/src/pages/SubmitItem/NavigationButtons/PreviousButton.tsx (1 hunks)
  • web/src/pages/SubmitItem/NavigationButtons/SubmitItemButton.tsx (1 hunks)
  • web/src/pages/SubmitItem/NavigationButtons/index.tsx (1 hunks)
  • web/src/pages/SubmitItem/Policy/ConfirmationBox.tsx (1 hunks)
  • web/src/pages/SubmitItem/Policy/Info.tsx (2 hunks)
  • web/src/pages/SubmitItem/Policy/ReadPolicy.tsx (1 hunks)
  • web/src/pages/SubmitItem/Policy/index.tsx (2 hunks)
  • web/src/pages/SubmitItem/Preview/ItemDisplay.tsx (1 hunks)
  • web/src/pages/SubmitItem/Preview/ListDisplay.tsx (2 hunks)
  • web/src/pages/SubmitItem/Preview/index.tsx (1 hunks)
  • web/src/pages/SubmitItem/Timeline.tsx (1 hunks)
  • web/src/pages/SubmitItem/Title.tsx (1 hunks)
  • web/src/pages/SubmitItem/index.tsx (2 hunks)
💤 Files with no reviewable changes (1)
  • web/src/pages/SubmitItem/ItemField/FieldInput/StyledField.tsx
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/styles/breakpoints.ts:1-1
Timestamp: 2025-11-14T22:12:39.974Z
Learning: In the kleros/curate-v2 repository, the kleros/ui-components-library overrides Tailwind's lg breakpoint to 900px (not the default 1024px). The LG_BREAKPOINT constant in web/src/styles/breakpoints.ts is set to 900 to match this override. This configuration is imported via the source directive in global.css.
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/index.tsx:15-28
Timestamp: 2025-10-24T21:25:59.174Z
Learning: In Tailwind v4, when using CSS variables from external libraries like kleros/ui-components-library, add the `source` directive in global.css to tell Tailwind to scan and generate utility classes from those variables. Example: `source "../node_modules/kleros/ui-components-library";`
📚 Learning: 2024-11-04T13:42:03.737Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/components/ActionButton/Modal/EvidenceUpload.tsx:74-82
Timestamp: 2024-11-04T13:42:03.737Z
Learning: In `web/src/components/ActionButton/Modal/EvidenceUpload.tsx`, the `uploadFile` function already manages error handling and logging, so additional error handling after calling it is unnecessary.

Applied to files:

  • web/src/pages/SubmitItem/ItemField/FieldInput/ImageInput.tsx
  • web/src/pages/SubmitItem/ItemField/FieldInput/FileInput.tsx
📚 Learning: 2024-11-04T13:41:01.846Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/EmailVerificationInfo.tsx:67-80
Timestamp: 2024-11-04T13:41:01.846Z
Learning: In React components, when a button is used within a form, calling `e.preventDefault()` in the event handler is necessary to prevent the default form submission, even when using an `onClick` handler.

Applied to files:

  • web/src/pages/SubmitItem/NavigationButtons/SubmitItemButton.tsx
  • web/src/pages/SubmitItem/NavigationButtons/PreviousButton.tsx
  • web/src/pages/SubmitItem/ItemField/index.tsx
  • web/src/pages/SubmitItem/NavigationButtons/NextButton.tsx
📚 Learning: 2024-11-04T13:34:45.425Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/utils/atlas/confirmEmail.ts:24-36
Timestamp: 2024-11-04T13:34:45.425Z
Learning: In the `confirmEmail` function in `web/src/utils/atlas/confirmEmail.ts`, input validation for the address is performed in the calling component, and additional checks are done in the API call itself. Input validation does not need to be repeated in this function.

Applied to files:

  • web/src/pages/SubmitItem/ItemField/FieldInput/AddressInput.tsx
📚 Learning: 2024-11-04T13:39:19.748Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/utils/atlas/updateEmail.ts:21-38
Timestamp: 2024-11-04T13:39:19.748Z
Learning: For the `updateEmail` function in `web/src/utils/atlas/updateEmail.ts`, input validation and error handling are performed in the component that utilizes it. Therefore, additional checks within this utility function are unnecessary.

Applied to files:

  • web/src/pages/SubmitItem/ItemField/FieldInput/AddressInput.tsx
🧬 Code graph analysis (12)
web/src/pages/SubmitItem/ItemField/FieldInput/ChainInput.tsx (1)
web/src/components/ChainIcon.tsx (1)
  • getChainName (27-44)
web/src/pages/SubmitItem/ItemField/FieldInput/ImageInput.tsx (1)
web/src/utils/index.ts (1)
  • cn (44-46)
web/src/pages/SubmitItem/Header/index.tsx (1)
web/src/utils/format.ts (2)
  • formatValue (11-15)
  • formatUnitsWei (9-9)
web/src/pages/SubmitItem/ItemField/FieldInput/TextInput.tsx (2)
web/src/pages/SubmitItem/ItemField/FieldInput/index.tsx (1)
  • IFieldInput (14-17)
web/src/utils/index.ts (1)
  • cn (44-46)
web/src/pages/SubmitItem/NavigationButtons/PreviousButton.tsx (1)
web/src/utils/index.ts (1)
  • isEmpty (13-13)
web/src/pages/SubmitItem/Policy/Info.tsx (1)
web/src/utils/index.ts (1)
  • cn (44-46)
web/src/pages/SubmitItem/Policy/ReadPolicy.tsx (1)
web/src/utils/getIpfsUrl.ts (1)
  • getIpfsUrl (4-8)
web/src/pages/SubmitItem/ItemField/FieldInput/NumberInput.tsx (2)
web/src/pages/SubmitItem/ItemField/FieldInput/index.tsx (1)
  • IFieldInput (14-17)
web/src/utils/index.ts (1)
  • cn (44-46)
web/src/pages/SubmitItem/ItemField/FieldInput/AddressInput.tsx (2)
web/src/pages/SubmitItem/ItemField/FieldInput/index.tsx (1)
  • IFieldInput (14-17)
web/src/utils/index.ts (1)
  • cn (44-46)
web/src/pages/SubmitItem/ItemField/FieldInput/FileInput.tsx (1)
web/src/utils/index.ts (1)
  • cn (44-46)
web/src/pages/SubmitItem/ItemField/FieldInput/LinkInput.tsx (2)
web/src/pages/SubmitItem/ItemField/FieldInput/index.tsx (1)
  • IFieldInput (14-17)
web/src/utils/index.ts (1)
  • cn (44-46)
web/src/pages/SubmitItem/ItemField/FieldInput/LongTextInput.tsx (2)
web/src/pages/SubmitItem/ItemField/FieldInput/index.tsx (1)
  • IFieldInput (14-17)
web/src/utils/index.ts (1)
  • cn (44-46)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Redirect rules - curate-v2
  • GitHub Check: Header rules - curate-v2
  • GitHub Check: Pages changed - curate-v2
🔇 Additional comments (20)
web/src/pages/SubmitItem/ItemField/FieldInput/BooleanInput.tsx (1)

10-10: Switch prop migration to isSelected appears correct

The controlled boolean logic is preserved and the new isSelected={valueAsBool} prop should align with the updated Switch API, assuming v3.6.0 indeed expects isSelected instead of checked. Please double-check the @kleros/ui-components-library docs to confirm the prop name and onChange signature match this usage.

web/src/pages/SubmitItem/ItemField/FieldInput/NumberInput.tsx (1)

10-12: LGTM!

The change from handling DOM events to handling numeric values aligns correctly with the NumberField API from @kleros/ui-components-library v3.

web/src/pages/SubmitItem/Policy/index.tsx (1)

13-22: LGTM!

Clean migration from styled-components to Tailwind classes. The flex flex-col layout preserves the original container behavior.

web/src/pages/SubmitItem/NavigationButtons/SubmitItemButton.tsx (1)

54-74: LGTM!

Correct migration of the Button API from disabled to isDisabled, consistent with @kleros/ui-components-library v3. The button logic and submission flow remain intact.

web/src/pages/SubmitItem/NavigationButtons/NextButton.tsx (1)

42-42: LGTM!

Correct update of the Button prop from disabled to isDisabled for compatibility with @kleros/ui-components-library v3.

web/src/pages/SubmitItem/Title.tsx (1)

8-8: LGTM!

Clean migration to Tailwind with proper semantic HTML. The responsive width classes correctly apply mobile-first styling.

web/src/pages/SubmitItem/ItemField/FieldInput/FileInput.tsx (1)

31-42: Good use of the cn utility for className composition.

The migration from styled-components to Tailwind classes is well-executed. The use of the cn utility allows for clean composition of multiple class strings, and the child selector syntax [&_small]:whitespace-pre-line correctly targets nested elements.

web/src/pages/SubmitItem/Policy/Info.tsx (1)

14-16: LGTM!

Clean migration to Tailwind classes with proper use of the cn utility for className composition.

web/src/pages/SubmitItem/ItemField/FieldInput/ImageInput.tsx (1)

33-44: LGTM!

Consistent migration pattern with FileInput.tsx. The className composition and upload flow are correctly implemented.

web/src/pages/SubmitItem/Header/index.tsx (1)

43-69: Well-structured refactor from styled-components.

The migration to a Card-based layout with Tailwind classes is clean and maintainable. The custom color classes (text-klerosUIComponentsPrimaryText, text-klerosUIComponentsSecondaryPurple) correctly use the theme tokens from the UI library, and the responsive layout logic is preserved.

web/src/pages/SubmitItem/Preview/ListDisplay.tsx (1)

22-32: LGTM! Clean migration to Tailwind classes.

The styled-components have been successfully replaced with Tailwind utility classes. The inline gap style using responsiveSize is retained for responsive behavior.

web/src/pages/SubmitItem/Timeline.tsx (1)

33-33: LGTM! Responsive behavior correctly migrated to Tailwind.

The styled-components wrapper has been successfully replaced with Tailwind utility classes. The timeline is hidden by default and becomes visible with absolute positioning on large screens (≥900px as per learnings).

web/src/pages/SubmitItem/NavigationButtons/PreviousButton.tsx (1)

14-19: LGTM! Conditional visibility correctly implemented.

The styled-components wrapper has been replaced with a className prop that conditionally applies hidden or flex based on whether prevRoute is empty. This maintains the same behavior while using Tailwind utilities.

web/src/pages/SubmitItem/ItemField/index.tsx (1)

31-44: LGTM! Clean migration to className-based styling.

The styled-components container has been successfully replaced with a plain div using Tailwind classes. The Skeleton components now use className for bottom margin spacing, maintaining the same visual layout.

web/src/pages/SubmitItem/NavigationButtons/index.tsx (1)

13-16: LGTM! Flex layout correctly migrated.

The styled Container has been replaced with a div using Tailwind flex utilities (flex flex-wrap justify-center gap-6). The responsive margin is preserved via inline style.

web/src/pages/SubmitItem/Preview/index.tsx (1)

22-22: Verify the purpose of this empty overlay div.

This absolutely positioned div appears to be a leftover from the Overlay styled component mentioned in the migration. Without background color, opacity, z-index, or pointer-events, it has no visual or interactive effect. Please verify whether this element is still needed or should be removed.

If this overlay is intentional, apply the necessary styling:

-        <div className="absolute w-full h-full" />
+        <div className="absolute inset-0 bg-black/50 z-10" /> {/* Example overlay styling */}

Or remove it if no longer needed:

-        <div className="absolute w-full h-full" />
web/src/pages/SubmitItem/Preview/ItemDisplay.tsx (1)

22-25: LGTM!

Clean migration from styled-components to Tailwind utility classes. The responsive sizing and custom color classes are correctly applied.

web/src/pages/SubmitItem/index.tsx (1)

47-47: The className prop is accepted, but only applied to the Button element when unverified.

The EnsureAuth component does accept and destructure the className prop correctly. However, the className is only forwarded to the internal Button component and is not applied when rendering children (in the verified state). This means className="self-center" only affects the styling of the "Sign In" button, not the overall EnsureAuth wrapper or verified content. Consider whether the className should also wrap the children or if this conditional behavior is intentional.

web/src/pages/SubmitItem/Policy/ConfirmationBox.tsx (2)

11-18: LGTM! Clean migration to Tailwind.

The replacement of the styled Container component with a plain div and Tailwind utility class mb-8 follows the PR's migration strategy correctly.


14-14: Verify isSelected prop compatibility by checking library source or running imports.

The PR follows a consistent naming pattern (e.g., disabledisDisabled for Button), and isSelected aligns with modern React UI library conventions. However, web searches did not return the specific @kleros/ui-components-library v3 Checkbox API documentation. To confirm the prop name:

  • Check the library's Checkbox component export in node_modules/@kleros/ui-components-library or its GitHub source
  • Run npm list @kleros/ui-components-library to verify v3 is installed
  • Review the type definitions (.d.ts) for the Checkbox component props interface

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (2)
web/src/pages/SubmitItem/ItemField/FieldInput/LinkInput.tsx (1)

11-17: Fix validation logic to allow user input.

The validation still blocks all user input when the URL is invalid. Users cannot type partial URLs because handleWrite is only called for complete, valid URLs, and the error state is never cleared.

Apply this diff to allow typing while providing validation feedback:

 const handleChange = (value: string) => {
-  if (!isValidUrl(value)) {
-    setIsError(true);
-    return;
-  }
-  handleWrite(value);
+  const isValid = value === "" || isValidUrl(value);
+  setIsError(!isValid && value !== "");
+  handleWrite(value);
 };

This allows users to type freely, shows an error for non-empty invalid URLs, and lets form-level validation prevent submission.

web/src/pages/SubmitItem/ItemField/FieldInput/NumberInput.tsx (1)

16-16: Fix NaN handling with nullish coalescing operator.

Number(fieldProp.value) ?? 0 does not handle NaN correctly. When fieldProp.value is undefined or an invalid numeric string, Number(fieldProp.value) returns NaN, and NaN ?? 0 evaluates to NaN (not 0) because the nullish coalescing operator only checks for null or undefined, not NaN.

Apply this diff:

-      value={Number(fieldProp.value) ?? 0}
+      value={Number(fieldProp.value) || 0}

Or for more explicit handling:

-      value={Number(fieldProp.value) ?? 0}
+      value={fieldProp.value ? Number(fieldProp.value) : 0}
🧹 Nitpick comments (1)
web/src/pages/SubmitItem/ItemField/FieldInput/constants.ts (1)

1-1: Consider using CSS custom properties or Tailwind's built-in responsive utilities.

The calc expression is mathematically correct but quite complex and difficult to maintain. Consider these alternatives:

  1. Define CSS custom properties in your theme for these fluid calculations
  2. Use Tailwind's clamp() plugin or custom spacing scale
  3. Document the formula's purpose (e.g., "Scales input width from 200px to 720px between mobile and desktop")

Example with CSS custom properties:

:root {
  --field-width-fluid: clamp(200px, 200px + (720 - 200) * ((100vw - 375px) / (1250 - 375)), 720px);
}

Then use: lg:w-[var(--field-width-fluid)]

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 299dcfa and 7c6e188.

📒 Files selected for processing (9)
  • web/src/pages/SubmitItem/ItemField/FieldInput/AddressInput.tsx (1 hunks)
  • web/src/pages/SubmitItem/ItemField/FieldInput/FileInput.tsx (2 hunks)
  • web/src/pages/SubmitItem/ItemField/FieldInput/ImageInput.tsx (2 hunks)
  • web/src/pages/SubmitItem/ItemField/FieldInput/LinkInput.tsx (1 hunks)
  • web/src/pages/SubmitItem/ItemField/FieldInput/LongTextInput.tsx (1 hunks)
  • web/src/pages/SubmitItem/ItemField/FieldInput/NumberInput.tsx (1 hunks)
  • web/src/pages/SubmitItem/ItemField/FieldInput/TextInput.tsx (1 hunks)
  • web/src/pages/SubmitItem/ItemField/FieldInput/constants.ts (1 hunks)
  • web/src/pages/SubmitItem/Policy/ConfirmationBox.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • web/src/pages/SubmitItem/ItemField/FieldInput/FileInput.tsx
  • web/src/pages/SubmitItem/Policy/ConfirmationBox.tsx
  • web/src/pages/SubmitItem/ItemField/FieldInput/TextInput.tsx
  • web/src/pages/SubmitItem/ItemField/FieldInput/AddressInput.tsx
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/styles/breakpoints.ts:1-1
Timestamp: 2025-11-14T22:12:39.974Z
Learning: In the kleros/curate-v2 repository, the kleros/ui-components-library overrides Tailwind's lg breakpoint to 900px (not the default 1024px). The LG_BREAKPOINT constant in web/src/styles/breakpoints.ts is set to 900 to match this override. This configuration is imported via the source directive in global.css.
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/index.tsx:15-28
Timestamp: 2025-10-24T21:25:59.174Z
Learning: In Tailwind v4, when using CSS variables from external libraries like kleros/ui-components-library, add the `source` directive in global.css to tell Tailwind to scan and generate utility classes from those variables. Example: `source "../node_modules/kleros/ui-components-library";`
📚 Learning: 2024-11-04T13:34:45.425Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/utils/atlas/confirmEmail.ts:24-36
Timestamp: 2024-11-04T13:34:45.425Z
Learning: In the `confirmEmail` function in `web/src/utils/atlas/confirmEmail.ts`, input validation for the address is performed in the calling component, and additional checks are done in the API call itself. Input validation does not need to be repeated in this function.

Applied to files:

  • web/src/pages/SubmitItem/ItemField/FieldInput/LinkInput.tsx
📚 Learning: 2024-11-04T13:39:19.748Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/utils/atlas/updateEmail.ts:21-38
Timestamp: 2024-11-04T13:39:19.748Z
Learning: For the `updateEmail` function in `web/src/utils/atlas/updateEmail.ts`, input validation and error handling are performed in the component that utilizes it. Therefore, additional checks within this utility function are unnecessary.

Applied to files:

  • web/src/pages/SubmitItem/ItemField/FieldInput/LinkInput.tsx
📚 Learning: 2024-11-04T13:42:03.737Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/components/ActionButton/Modal/EvidenceUpload.tsx:74-82
Timestamp: 2024-11-04T13:42:03.737Z
Learning: In `web/src/components/ActionButton/Modal/EvidenceUpload.tsx`, the `uploadFile` function already manages error handling and logging, so additional error handling after calling it is unnecessary.

Applied to files:

  • web/src/pages/SubmitItem/ItemField/FieldInput/ImageInput.tsx
📚 Learning: 2025-11-14T22:12:39.974Z
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/styles/breakpoints.ts:1-1
Timestamp: 2025-11-14T22:12:39.974Z
Learning: In the kleros/curate-v2 repository, the kleros/ui-components-library overrides Tailwind's lg breakpoint to 900px (not the default 1024px). The LG_BREAKPOINT constant in web/src/styles/breakpoints.ts is set to 900 to match this override. This configuration is imported via the source directive in global.css.

Applied to files:

  • web/src/pages/SubmitItem/ItemField/FieldInput/constants.ts
🧬 Code graph analysis (4)
web/src/pages/SubmitItem/ItemField/FieldInput/NumberInput.tsx (3)
web/src/pages/SubmitItem/ItemField/FieldInput/index.tsx (1)
  • IFieldInput (14-17)
web/src/utils/index.ts (1)
  • cn (44-46)
web/src/pages/SubmitItem/ItemField/FieldInput/constants.ts (1)
  • LANDSCAPE_WIDTH_CALC (1-1)
web/src/pages/SubmitItem/ItemField/FieldInput/LinkInput.tsx (3)
web/src/pages/SubmitItem/ItemField/FieldInput/index.tsx (1)
  • IFieldInput (14-17)
web/src/utils/index.ts (1)
  • cn (44-46)
web/src/pages/SubmitItem/ItemField/FieldInput/constants.ts (1)
  • LANDSCAPE_WIDTH_CALC (1-1)
web/src/pages/SubmitItem/ItemField/FieldInput/ImageInput.tsx (2)
web/src/utils/index.ts (1)
  • cn (44-46)
web/src/pages/SubmitItem/ItemField/FieldInput/constants.ts (2)
  • MARGIN_BOTTOM_CALC (2-2)
  • LANDSCAPE_WIDTH_CALC (1-1)
web/src/pages/SubmitItem/ItemField/FieldInput/LongTextInput.tsx (3)
web/src/pages/SubmitItem/ItemField/FieldInput/index.tsx (1)
  • IFieldInput (14-17)
web/src/utils/index.ts (1)
  • cn (44-46)
web/src/pages/SubmitItem/ItemField/FieldInput/constants.ts (1)
  • LANDSCAPE_WIDTH_CALC (1-1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Redirect rules - curate-v2
  • GitHub Check: Header rules - curate-v2
  • GitHub Check: Pages changed - curate-v2
🔇 Additional comments (2)
web/src/pages/SubmitItem/ItemField/FieldInput/ImageInput.tsx (1)

31-42: Verify intentional width difference for FileUploader.

This component uses w-[84vw] while other field inputs (LinkInput, NumberInput, LongTextInput) use w-[80vw]. Is this 4vw difference intentional for the FileUploader component, or should it be consistent?

If consistent width is desired, apply this diff:

-        "w-[84vw]",
+        "w-[80vw]",
web/src/pages/SubmitItem/ItemField/FieldInput/LongTextInput.tsx (1)

8-23: LGTM! Clean migration to TextArea component.

The refactor correctly migrates from styled-components to the UI library's TextArea component with proper responsive styling. The handleChange implementation correctly passes values through without blocking user input.

coderabbitai[bot]
coderabbitai bot previously approved these changes Nov 19, 2025
coderabbitai[bot]
coderabbitai bot previously approved these changes Nov 19, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (6)
web/src/pages/SubmitList/ListParameters/ListPreview/ListPageDisplay.tsx (1)

15-16: Consider using Tailwind's responsive variants instead of mixing inline styles.

The code mixes inline style={{ gap: responsiveSize(32, 24) }} with Tailwind utility classes. Tailwind v4 provides responsive variants (lg:gap-8, gap-6, etc.) and arbitrary values (gap-[32px]) to handle responsive spacing without inline styles. This approach would be more consistent with the Tailwind migration.

Example refactor using responsive variants:

-    <div className="flex flex-col" style={{ gap: responsiveSize(32, 24) }}>
+    <div className="flex flex-col gap-6 lg:gap-8">

Note: Adjust the exact gap values to match your breakpoint requirements (based on learnings, lg is 900px in your setup).

web/src/pages/SubmitList/ListParameters/ListPreview/index.tsx (1)

17-21: Consider using Tailwind's responsive variants instead of mixing inline styles.

Similar to the issue in ListPageDisplay.tsx, this code mixes inline responsiveSize() calls with Tailwind utilities. Tailwind v4 provides responsive variants and arbitrary values that would be more idiomatic.

Example refactor:

-        style={{
-          marginBottom: responsiveSize(0, 16),
-          paddingBlock: responsiveSize(24, 48),
-          paddingInline: responsiveSize(24, 32),
-        }}
+        style={{
+          marginBottom: 0,
+        }}
+        className={clsx(
+          "relative flex flex-col gap-8 w-full h-auto min-h-[100px]",
+          "border-dashed border-klerosUIComponentsPrimaryBlue bg-klerosUIComponentsMediumBlue",
+          "py-6 px-6 lg:py-12 lg:px-8 lg:mb-4"
+        )}

Or remove the inline style entirely if marginBottom: 0 is the default.

web/src/pages/SubmitList/ListParameters/ListPreview/HomePageDisplay.tsx (1)

13-13: Consider using Tailwind responsive gap utilities for consistency.

The inline style for gap mixes Tailwind classes with inline styles. Since the project has migrated to Tailwind v4 with custom breakpoints configured, consider using Tailwind's responsive gap utilities instead.

Apply this diff to use Tailwind gap utilities:

-    <div className="flex flex-col" style={{ gap: responsiveSize(32, 24) }}>
+    <div className="flex flex-col gap-6 lg:gap-8">

Note: Adjust the spacing values (gap-6 = 24px, gap-8 = 32px) if the Tailwind spacing scale differs. If the exact pixel values are required, use arbitrary values: gap-[24px] lg:gap-[32px].

web/src/pages/SubmitList/Timeline.tsx (1)

33-33: Consider using the cn utility for consistency.

While the className string is correct, consider using the cn utility (already used in other components like Title.tsx) for better consistency and maintainability across the codebase.

-  return <Steps className="hidden lg:absolute lg:flex lg:left-[2%] lg:h-[360px]" {...{ items, currentItemIndex }} />;
+  return <Steps className={cn("hidden lg:absolute lg:flex lg:left-[2%] lg:h-[360px]")} {...{ items, currentItemIndex }} />;

Based on learnings

web/src/pages/SubmitList/constants.ts (1)

1-5: Document the fluid responsive calculation formulas.

The calc expressions implement fluid responsive sizing, but the formulas are complex and lack documentation. Consider adding comments to explain the interpolation ranges for future maintainability.

 export const BASE_CONTAINER_STYLE = "flex flex-col items-center gap-8 w-[84vw]";
+
+// Fluid width: interpolates from 442px to 700px between 900px and 1250px viewport width
 export const BASE_CONTAINER_LANDSCAPE_WIDTH_CALC =
   "lg:w-[calc(442px+(700-442)*(min(max(100vw,900px),1250px)-900px)/(1250-900))]";
+
+// Fluid margin-bottom: interpolates from 150px to 72px between 375px and 1250px viewport width
 export const FILE_UPLOADER_MARGIN_BOTTOM_CALC =
   "mb-[calc(150px+(72-150)*(min(max(100vw,375px),1250px)-375px)/(1250-375))]";
web/src/pages/SubmitList/ListParameters/LogoUpload.tsx (1)

60-61: Consider the fragility of the [&_small] selector pattern.

The [&_small]:whitespace-pre-line [&_small]:text-start selectors target child <small> elements within the FileUploader component. This couples your styling to the internal DOM structure of @kleros/ui-components-library.

If the library changes its markup (e.g., removes <small> tags or alters the hierarchy), these styles will silently break. Consider:

  • Using the library's className props if available for message elements
  • Requesting the library to expose className props for better styling control
  • Documenting this dependency for future maintenance

The pattern is intentional (also used in Policy.tsx line 57), but be aware of the maintenance cost.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1afa675 and 6cf84d1.

📒 Files selected for processing (14)
  • web/src/pages/SubmitList/Header.tsx (1 hunks)
  • web/src/pages/SubmitList/ListParameters/Description.tsx (1 hunks)
  • web/src/pages/SubmitList/ListParameters/ListPreview/HomePageDisplay.tsx (2 hunks)
  • web/src/pages/SubmitList/ListParameters/ListPreview/ListPageDisplay.tsx (2 hunks)
  • web/src/pages/SubmitList/ListParameters/ListPreview/index.tsx (1 hunks)
  • web/src/pages/SubmitList/ListParameters/LogoUpload.tsx (3 hunks)
  • web/src/pages/SubmitList/ListParameters/Policy.tsx (3 hunks)
  • web/src/pages/SubmitList/ListParameters/Title.tsx (1 hunks)
  • web/src/pages/SubmitList/NavigationButtons/NextButton.tsx (1 hunks)
  • web/src/pages/SubmitList/NavigationButtons/PreviousButton.tsx (1 hunks)
  • web/src/pages/SubmitList/NavigationButtons/SubmitListButton.tsx (1 hunks)
  • web/src/pages/SubmitList/NavigationButtons/index.tsx (1 hunks)
  • web/src/pages/SubmitList/Timeline.tsx (1 hunks)
  • web/src/pages/SubmitList/constants.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (6)
📓 Common learnings
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/styles/breakpoints.ts:1-1
Timestamp: 2025-11-14T22:12:39.974Z
Learning: In the kleros/curate-v2 repository, the kleros/ui-components-library overrides Tailwind's lg breakpoint to 900px (not the default 1024px). The LG_BREAKPOINT constant in web/src/styles/breakpoints.ts is set to 900 to match this override. This configuration is imported via the source directive in global.css.
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/index.tsx:15-28
Timestamp: 2025-10-24T21:25:59.174Z
Learning: In Tailwind v4, when using CSS variables from external libraries like kleros/ui-components-library, add the `source` directive in global.css to tell Tailwind to scan and generate utility classes from those variables. Example: `source "../node_modules/kleros/ui-components-library";`
📚 Learning: 2024-11-04T13:33:39.755Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/pages/Settings/index.tsx:18-26
Timestamp: 2024-11-04T13:33:39.755Z
Learning: In `web/src/pages/Settings/index.tsx`, the parent route handles the default `/settings` route, error boundaries, and loading states, so it's not necessary to include them in this component.

Applied to files:

  • web/src/pages/SubmitList/NavigationButtons/index.tsx
📚 Learning: 2025-11-14T22:12:39.974Z
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/styles/breakpoints.ts:1-1
Timestamp: 2025-11-14T22:12:39.974Z
Learning: In the kleros/curate-v2 repository, the kleros/ui-components-library overrides Tailwind's lg breakpoint to 900px (not the default 1024px). The LG_BREAKPOINT constant in web/src/styles/breakpoints.ts is set to 900 to match this override. This configuration is imported via the source directive in global.css.

Applied to files:

  • web/src/pages/SubmitList/constants.ts
📚 Learning: 2024-11-04T13:31:54.080Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx:72-96
Timestamp: 2024-11-04T13:31:54.080Z
Learning: In the React TypeScript component `FormContactDetails` in `web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx`, error handling and user feedback are implemented within the `addUser` and `updateEmail` functions, which display toasts to the user.

Applied to files:

  • web/src/pages/SubmitList/ListParameters/Title.tsx
📚 Learning: 2024-11-04T13:41:01.846Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/EmailVerificationInfo.tsx:67-80
Timestamp: 2024-11-04T13:41:01.846Z
Learning: In React components, when a button is used within a form, calling `e.preventDefault()` in the event handler is necessary to prevent the default form submission, even when using an `onClick` handler.

Applied to files:

  • web/src/pages/SubmitList/NavigationButtons/PreviousButton.tsx
📚 Learning: 2024-11-04T13:42:03.737Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/components/ActionButton/Modal/EvidenceUpload.tsx:74-82
Timestamp: 2024-11-04T13:42:03.737Z
Learning: In `web/src/components/ActionButton/Modal/EvidenceUpload.tsx`, the `uploadFile` function already manages error handling and logging, so additional error handling after calling it is unnecessary.

Applied to files:

  • web/src/pages/SubmitList/ListParameters/LogoUpload.tsx
🧬 Code graph analysis (5)
web/src/pages/SubmitList/ListParameters/Description.tsx (3)
web/src/context/SubmitListContext.tsx (1)
  • useSubmitListContext (123-123)
web/src/utils/index.ts (1)
  • cn (44-46)
web/src/pages/SubmitList/constants.ts (2)
  • BASE_CONTAINER_STYLE (1-1)
  • BASE_CONTAINER_LANDSCAPE_WIDTH_CALC (2-3)
web/src/pages/SubmitList/ListParameters/Title.tsx (3)
web/src/context/SubmitListContext.tsx (1)
  • useSubmitListContext (123-123)
web/src/utils/index.ts (1)
  • cn (44-46)
web/src/pages/SubmitList/constants.ts (2)
  • BASE_CONTAINER_STYLE (1-1)
  • BASE_CONTAINER_LANDSCAPE_WIDTH_CALC (2-3)
web/src/pages/SubmitList/NavigationButtons/PreviousButton.tsx (1)
web/src/utils/index.ts (1)
  • isEmpty (13-13)
web/src/pages/SubmitList/ListParameters/LogoUpload.tsx (2)
web/src/utils/index.ts (1)
  • cn (44-46)
web/src/pages/SubmitList/constants.ts (3)
  • BASE_CONTAINER_STYLE (1-1)
  • BASE_CONTAINER_LANDSCAPE_WIDTH_CALC (2-3)
  • FILE_UPLOADER_MARGIN_BOTTOM_CALC (4-5)
web/src/pages/SubmitList/ListParameters/Policy.tsx (2)
web/src/utils/index.ts (2)
  • cn (44-46)
  • getFileUploaderMsg (23-42)
web/src/pages/SubmitList/constants.ts (3)
  • BASE_CONTAINER_STYLE (1-1)
  • BASE_CONTAINER_LANDSCAPE_WIDTH_CALC (2-3)
  • FILE_UPLOADER_MARGIN_BOTTOM_CALC (4-5)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Redirect rules - curate-v2
  • GitHub Check: Header rules - curate-v2
  • GitHub Check: Pages changed - curate-v2
🔇 Additional comments (18)
web/src/pages/SubmitList/ListParameters/ListPreview/HomePageDisplay.tsx (1)

14-14: The custom color class is properly configured and working.

The text-klerosUIComponentsPrimaryBlue utility class is correctly generated by Tailwind v4 from the CSS variables exported by @kleros/ui-components-library (v3.6.0). The @source directive in global.css is properly configured to scan the library for CSS variables, and this pattern is used successfully across 20+ files in the codebase without issues.

web/src/pages/SubmitList/NavigationButtons/NextButton.tsx (1)

43-43: LGTM! Clean API migration.

The prop rename from disabled to isDisabled correctly aligns with the @kleros/ui-components-library v3 API.

web/src/pages/SubmitList/NavigationButtons/SubmitListButton.tsx (2)

232-232: LGTM! Correct prop migration.

The isDisabled prop correctly replaces the deprecated disabled prop, consistent with the library v3 API.


231-233: I'll search for the Button component API documentation for @kleros/ui-components-library v3.6.0.

Let me search more specifically for the Button component's TypeScript types and props for this library.

Let me search more directly for the Kleros library Button component.

Based on my web search attempts, I was unable to find specific documentation for the @kleros/ui-components-library v3.6.0 Button component's Icon prop API in publicly available sources. The GitHub repository and NPM package listings do not expose detailed TypeScript types or prop documentation in search results.

Unable to verify Icon prop API via web search. The @kleros/ui-components-library v3.6.0 Button component's Icon prop specification is not documented in publicly available sources. You need to verify this directly by:

  1. Checking the installed package types: node_modules/@kleros/ui-components-library/dist/components/Button or similar path
  2. Reviewing the library's TypeScript definition files (.d.ts)
  3. Consulting the library's Storybook or GitHub releases page for v3.6.0
  4. Running a quick test to confirm Icon={CheckCircle} compiles without errors
web/src/pages/SubmitList/NavigationButtons/PreviousButton.tsx (1)

21-27: LGTM! Clean migration to utility classes.

The Button component correctly:

  • Uses conditional className logic to toggle visibility based on prevRoute
  • Migrates to the isDisabled prop
  • Preserves the original hide/show and navigation behavior
web/src/pages/SubmitList/NavigationButtons/index.tsx (1)

12-15: LGTM! Straightforward styled-components removal.

The replacement of the styled Container with a plain div using Tailwind utility classes is clean and maintains the same layout behavior.

web/src/pages/SubmitList/Header.tsx (1)

8-8: LGTM! Clean styled-components removal.

The h1 element with Tailwind utilities correctly replaces the styled Container. The responsive width classes (w-[84vw] lg:w-auto) maintain the original behavior.

Based on learnings

web/src/pages/SubmitList/ListParameters/Title.tsx (2)

17-29: Excellent use of shared constants and cn utility.

The migration to TextField with shared layout constants (BASE_CONTAINER_STYLE, BASE_CONTAINER_LANDSCAPE_WIDTH_CALC) and the cn utility promotes consistency and maintainability across the SubmitList feature.


13-15: TextField onChange API usage is correct and verified.

The handler signature in Title.tsx properly receives a value: string parameter directly from the @kleros/ui-components-library TextField component. This is confirmed by consistent usage patterns throughout the codebase—for example, FormContact.tsx uses onChange={(value) => setContactInput(value)}, confirming that the onChange handler receives the value directly, not an event object.

The implementation is compatible with @kleros/ui-components-library v3.6.0 and follows the library's documented API pattern.

web/src/pages/SubmitList/ListParameters/LogoUpload.tsx (2)

9-15: LGTM: Imports properly support the Tailwind migration.

The imports correctly bring in the cn utility for class composition and centralized layout constants, supporting the migration away from styled-components.


58-58: LGTM: Container properly migrated to Tailwind classes.

The container correctly uses cn() to compose the base container style with the landscape width calculation.

web/src/pages/SubmitList/ListParameters/Description.tsx (3)

8-8: LGTM: Constants import is correct.

Properly imports the centralized layout constants for consistent styling across SubmitList pages.


12-14: LGTM: Handler correctly updated for TextField API.

The handleWrite signature properly changed from accepting a React ChangeEvent to accepting a string value directly, aligning with the new TextField component's onChange API.


16-32: LGTM: Component structure cleanly migrated to Tailwind.

The layout properly uses centralized constants for the container and applies Tailwind utilities for the inner structure. The TextField and InfoCard are correctly configured.

web/src/pages/SubmitList/ListParameters/Policy.tsx (4)

10-16: LGTM: Imports are correct and consistent.

The imports properly support the Tailwind migration with the correct path (src/utils without tilde) and centralized layout constants.


41-41: LGTM: Container properly migrated to Tailwind classes.

The container correctly uses cn() to compose layout constants, consistent with the other SubmitList pages.


43-55: LGTM: Label properly migrated to use className.

The label correctly uses className="w-full" instead of styled-components, maintaining the same content and Link structure.


56-57: LGTM: FileUploader properly migrated to Tailwind classes.

The FileUploader correctly uses cn() to compose classes including the [&_small] selector pattern. Note that the same fragility concern regarding the [&_small] selector mentioned in the LogoUpload.tsx review (lines 60-61) applies here as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Frontend migration to the major update of @kleros/ui-components-library v3 with Tailwind

2 participants